diff --git a/src/assets/LD-icon-new.png b/src/assets/LD-icon-new.png new file mode 100644 index 00000000..ada9868d Binary files /dev/null and b/src/assets/LD-icon-new.png differ diff --git a/src/shared/storage/OptionsStore.ts b/src/shared/storage/OptionsStore.ts index d1807dd4..33291ead 100644 --- a/src/shared/storage/OptionsStore.ts +++ b/src/shared/storage/OptionsStore.ts @@ -21,6 +21,9 @@ export interface IOptionsStore { /** whether the calendar sidebar should be shown when the calendar is opened */ showCalendarSidebar: boolean; + + /** whether the promo should be shown */ + showUTDiningPromo: boolean; } export const OptionsStore = createSyncStore({ @@ -30,6 +33,7 @@ export const OptionsStore = createSyncStore({ enableDataRefreshing: false, alwaysOpenCalendarInNewTab: false, showCalendarSidebar: true, + showUTDiningPromo: true, }); /** @@ -45,6 +49,7 @@ export const initSettings = async () => enableDataRefreshing: await OptionsStore.get('enableDataRefreshing'), alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'), showCalendarSidebar: await OptionsStore.get('showCalendarSidebar'), + showUTDiningPromo: await OptionsStore.get('showUTDiningPromo'), }) satisfies IOptionsStore; // Clothing retailer right diff --git a/src/shared/util/appUrls.ts b/src/shared/util/appUrls.ts new file mode 100644 index 00000000..fde044b1 --- /dev/null +++ b/src/shared/util/appUrls.ts @@ -0,0 +1,19 @@ +/** + * This file contains URLs for external applications and resources. + * Centralizing these URLs makes it easier to track, update, and manage them in a single place. + */ + +/** + * URL to the UT Dining app on the App Store + */ +export const UT_DINING_APP_STORE_URL = new URL('https://apps.apple.com/us/app/ut-dining/id6743042002').toString(); + +/** + * URL to the UT Dining app on the Google Play Store (currently not available) + */ +export const UT_DINING_GOOGLE_PLAY_URL = ''; // Placeholder for Google Play URL, Android app not available yet + +/** + * URL to the promo image + */ +export const UT_DINING_PROMO_IMAGE_URL = new URL('https://cdn.longhorns.dev/ut-dining-advert1.png').toString(); diff --git a/src/stories/components/DiningAppPromo.stories.tsx b/src/stories/components/DiningAppPromo.stories.tsx new file mode 100644 index 00000000..d23e13c9 --- /dev/null +++ b/src/stories/components/DiningAppPromo.stories.tsx @@ -0,0 +1,14 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import DiningAppPromo from '@views/components/calendar/DiningAppPromo'; + +export default { + title: 'Components/Calendar/DiningAppPromo', + component: DiningAppPromo, + parameters: { + layout: 'centered', + }, +} satisfies Meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/src/views/components/calendar/Calendar.tsx b/src/views/components/calendar/Calendar.tsx index 8fde938c..0c26f21c 100644 --- a/src/views/components/calendar/Calendar.tsx +++ b/src/views/components/calendar/Calendar.tsx @@ -27,6 +27,7 @@ import { Button } from '../common/Button'; import { LargeLogo } from '../common/LogoIcon'; import Text from '../common/Text/Text'; import CalendarFooter from './CalendarFooter'; +import DiningAppPromo from './DiningAppPromo'; /** * Calendar page component @@ -41,6 +42,8 @@ export default function Calendar(): ReactNode { const [showPopup, setShowPopup] = useState(course !== null); const showWhatsNewDialog = useWhatsNewPopUp(); + const [showUTDiningPromo, setShowUTDiningPromo] = useState(false); + const queryClient = useQueryClient(); const { data: showSidebar, isPending: isSidebarStatePending } = useQuery({ queryKey: ['settings', 'showCalendarSidebar'], @@ -82,12 +85,19 @@ export default function Calendar(): ReactNode { if (course) setShowPopup(true); }, [course]); + useEffect(() => { + // Load the user's preference for the promo + OptionsStore.get('showUTDiningPromo').then(show => { + setShowUTDiningPromo(show); + }); + }, []); + if (isSidebarStatePending) return null; return (
-
+
- {/* */} + + {showUTDiningPromo && ( + { + setShowUTDiningPromo(false); + OptionsStore.set('showUTDiningPromo', false); + }} + /> + )}
void; +} + +/** + * Promotional component for the UT Dining app + */ +export default function DiningAppPromo({ onClose }: DiningAppPromoProps) { + return ( +
+
+ +
+
+ + Download our new{' '} + + UT Dining app + {' '} + to explore all dining options on campus! + +
+ + Available on + + + + + {/* + + */} +
+
+
+ ); +} diff --git a/src/views/components/calendar/ImportantLinks.tsx b/src/views/components/calendar/ImportantLinks.tsx index 38b02b46..4f8a44b8 100644 --- a/src/views/components/calendar/ImportantLinks.tsx +++ b/src/views/components/calendar/ImportantLinks.tsx @@ -13,10 +13,10 @@ interface LinkItem { } const links: LinkItem[] = [ - { - text: "Spring '25 Course Schedule", - url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20252/', - }, + // { + // text: "Spring '25 Course Schedule", + // url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20252/', + // }, { text: 'Course Schedule Archives', url: 'https://registrar.utexas.edu/schedules/archive', diff --git a/src/views/components/calendar/ResourceLinks.tsx b/src/views/components/calendar/ResourceLinks.tsx index 797e63b2..ed8782d1 100644 --- a/src/views/components/calendar/ResourceLinks.tsx +++ b/src/views/components/calendar/ResourceLinks.tsx @@ -22,10 +22,10 @@ const links: LinkItem[] = [ text: "Summer '25 Course Schedule", url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20256/', }, - { - text: "Spring '25 Course Schedule", - url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20252/', - }, + // { + // text: "Spring '25 Course Schedule", + // url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20252/', + // }, { text: 'Course Schedule Archives', url: 'https://registrar.utexas.edu/schedules/archive', diff --git a/src/views/components/common/ScheduleDropdown.tsx b/src/views/components/common/ScheduleDropdown.tsx index aef5a665..57173a78 100644 --- a/src/views/components/common/ScheduleDropdown.tsx +++ b/src/views/components/common/ScheduleDropdown.tsx @@ -24,7 +24,7 @@ export default function ScheduleDropdown({ defaultOpen, children }: ScheduleDrop {({ open }) => ( <> -
+
- UTRP Map - - BETA - -
- ), - description: 'Find directions to your classes with our beta map feature in the settings page', + id: 'microwave-map', + icon: MapTrifold, + title: 'Microwave Map', + description: 'Need to heat up your lunch? Find microwaves across campus!', }, ] as const satisfies readonly Feature[]; @@ -97,14 +91,11 @@ export default function WhatsNewPopupContent(): JSX.Element {
) : ( - + UT Dining Promo )}
diff --git a/src/views/hooks/useWhatsNew.tsx b/src/views/hooks/useWhatsNew.tsx index d803cc87..320d33b9 100644 --- a/src/views/hooks/useWhatsNew.tsx +++ b/src/views/hooks/useWhatsNew.tsx @@ -1,3 +1,4 @@ +import { UT_DINING_APP_STORE_URL } from '@shared/util/appUrls'; import { Button } from '@views/components/common/Button'; import Text from '@views/components/common/Text/Text'; import WhatsNewPopupContent from '@views/components/common/WhatsNewPopup'; @@ -7,6 +8,8 @@ import React from 'react'; import { LogoIcon } from '../components/common/LogoIcon'; import useChangelog from './useChangelog'; +const LDIconURL = new URL('/src/assets/LD-icon-new.png', import.meta.url).href; + /** * Custom hook that provides a function to display a what's new dialog. * @@ -22,20 +25,26 @@ export default function useWhatsNewPopUp(): () => void { className: 'w-[830px] flex flex-col items-center gap-spacing-7 p-spacing-8', title: (
- + LD Icon - What's New in UT Registration Plus + Download our new UT Dining app!
), description: , buttons: (
-
),