Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cart page (2) #141

Merged
merged 37 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
54727a6
Implement cart page
raymosun Jan 29, 2024
12e54a0
Restore missing API function
raymosun Jan 29, 2024
fc4176f
Clean up code
raymosun Jan 29, 2024
b1c833c
Update dropped file
raymosun Jan 29, 2024
6a25eb6
Integrate with real linkedEvent
raymosun Jan 29, 2024
00607c6
Messing with supporting pickup events lacking linked event
raymosun Feb 1, 2024
5eb26a8
Clean up some code
raymosun Feb 5, 2024
56f092a
Clean up more code
raymosun Feb 5, 2024
9d184de
Refactor mock cart to debug page
raymosun Feb 5, 2024
046ac56
Fix some lil bugs
raymosun Feb 6, 2024
10cd009
Fix error message
raymosun Feb 12, 2024
edb559a
Implement warnings for sold-out/limit-reachecd items
raymosun Feb 12, 2024
88b7460
Fix some dpc comments
raymosun Feb 12, 2024
acc235e
Merge branch 'main' into raymond/store-cart-page-ii
raymosun Feb 12, 2024
b2d1d40
Update criteria for showing /debug page
raymosun Feb 12, 2024
5e54e0c
Merge branch 'raymond/store-cart-page-ii' of https://github.com/acmuc…
raymosun Feb 12, 2024
81c107a
Rework confirmation to omit modal-in-modal
raymosun Feb 13, 2024
df47a9f
Fix prop type
raymosun Feb 13, 2024
3c5f154
Add back button
raymosun Feb 13, 2024
2dfb5b2
Fix event confirmation modal width
raymosun Feb 13, 2024
48be788
Refactor placeMerchOrder to StoreManager
raymosun Feb 15, 2024
befa3ad
Merge branch 'main' into raymond/store-cart-page-ii
raymosun Feb 27, 2024
e9a8f7d
Fix merge problems
raymosun Feb 27, 2024
5fad921
Fix more merge problems
raymosun Feb 27, 2024
fe55861
Fix more merge problems (2)
raymosun Feb 27, 2024
655bf86
Fix more merge problems (3) 🙄
raymosun Feb 27, 2024
f4fae15
Fix some nits
raymosun Feb 27, 2024
7bd9578
Update remove/cancel buttons
raymosun Mar 4, 2024
2986fa8
Fix bug with uuid for pickup events
raymosun Mar 4, 2024
0476a72
Updated event picker cards with no modal
raymosun Mar 4, 2024
e47cb8a
Refactor event width from css
raymosun Mar 4, 2024
abae27d
Remove unnecessary ??
raymosun Mar 4, 2024
a443204
Update purchase limit messages
raymosun Mar 4, 2024
9006377
Merge branch 'main' into raymond/store-cart-page-ii
raymosun Mar 4, 2024
2600c8e
Fix merge bug
raymosun Mar 4, 2024
fe47539
Merge branch 'main' into raymond/store-cart-page-ii
raymosun Mar 5, 2024
cd1e3a6
Weird stuff
raymosun Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/assets/icons/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/assets/icons/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/icons/empty-cart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 44 additions & 15 deletions src/components/events/EventCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,70 @@
import { CommunityLogo, Typography } from '@/components/common';
import EventModal from '@/components/events/EventModal';
import PointsDisplay from '@/components/events/PointsDisplay';
import { PublicEvent } from '@/lib/types/apiResponses';
import { formatEventDate } from '@/lib/utils';
import {
PublicEvent,
PublicOrderPickupEvent,
PublicOrderPickupEventWithLinkedEvent,
} from '@/lib/types/apiResponses';
import { formatEventDate, isOrderPickupEvent } from '@/lib/utils';
import Image from 'next/image';
import { useState } from 'react';
import styles from './style.module.scss';

interface EventCardProps {
event: PublicEvent;
event: PublicEvent | PublicOrderPickupEvent;
attended: boolean;
className?: string;
showYear?: boolean;
borderless?: boolean;
hideInfo?: boolean;
}

const EventCard = ({ event, attended, className, showYear, hideInfo }: EventCardProps) => {
const { cover, title, start, end, location } = event;
const EventCard = ({
event,
attended,
className,
showYear,
borderless,
hideInfo,
}: EventCardProps) => {
const { cover, title, start, end, location, committee } = isOrderPickupEvent(event)
? {
...(event.linkedEvent ?? {}),
...event,
}
: event;

const [expanded, setExpanded] = useState(false);
const hasModal = !isOrderPickupEvent(event) || event.linkedEvent;

const displayCover = cover || '/assets/graphics/store/hero-photo.jpg';

return (
<>
<EventModal
open={expanded}
attended={attended}
event={event}
onClose={() => setExpanded(false)}
/>
{hasModal && (
<EventModal
open={expanded}
attended={attended}
event={
isOrderPickupEvent(event)
? (event as PublicOrderPickupEventWithLinkedEvent).linkedEvent
: event
}
onClose={() => setExpanded(false)}
/>
)}

<button
type="button"
className={`${styles.container} ${className || ''}`}
className={`${styles.container} ${borderless ? '' : styles.bordered} ${className || ''}`}
onClick={() => setExpanded(true)}
disabled={!hasModal}
>
<div className={styles.image}>
<PointsDisplay points={event.pointValue} attended={attended} />
{!isOrderPickupEvent(event) && (
<PointsDisplay points={event.pointValue} attended={attended} />
)}
<Image
src={displayCover}
alt="Event Cover Image"
Expand All @@ -44,10 +73,10 @@ const EventCard = ({ event, attended, className, showYear, hideInfo }: EventCard
fill
/>
</div>
{hideInfo ? null : (
{!hideInfo && (
<div className={styles.info}>
<div className={styles.header}>
<CommunityLogo community={event.committee} size={50} />
<CommunityLogo community={committee ?? 'General'} size={50} />
<div className={styles.eventDetails}>
<Typography
variant="body/medium"
Expand Down
11 changes: 10 additions & 1 deletion src/components/events/EventCard/style.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,20 @@
transition: all 0.3s;
width: 20rem;

&:hover {
&.bordered {
border: 1px solid var(--theme-primary-6);
border-radius: 10px;
}

&:not([disabled]):hover {
box-shadow: 0 0 8px var(--theme-primary-6);
transform: scale(1.025);
}

&:disabled {
cursor: default;
}

.image {
aspect-ratio: 1920 / 1080;
flex-shrink: 0;
Expand Down
1 change: 1 addition & 0 deletions src/components/events/EventCard/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type Styles = {
bordered: string;
container: string;
eventDetails: string;
header: string;
Expand Down
94 changes: 94 additions & 0 deletions src/components/events/EventDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { CommunityLogo, Typography } from '@/components/common';
import CalendarButtons from '@/components/events/CalendarButtons';
import PointsDisplay from '@/components/events/PointsDisplay';
import { PublicEvent, PublicOrderPickupEvent } from '@/lib/types/apiResponses';
import { fixUrl, formatEventDate, isOrderPickupEvent } from '@/lib/utils';
import CloseIcon from '@/public/assets/icons/close-icon.svg';
import LinkIcon from '@/public/assets/icons/link.svg';
import Image from 'next/image';
import Link from 'next/link';
import styles from './style.module.scss';

interface EventDetailProps {
event: PublicEvent | PublicOrderPickupEvent;
attended: boolean;
/** controls whether a close button is shown */
inModal?: boolean;
raymosun marked this conversation as resolved.
Show resolved Hide resolved
}

const EventDetail = ({ event, attended, inModal = true }: EventDetailProps) => {
const { cover, title, start, end, location, committee, pointValue, eventLink, description } =
isOrderPickupEvent(event)
? {
...(event.linkedEvent ?? {}),
...event,
}
: event;

const displayCover = cover || '/assets/graphics/store/hero-photo.jpg';
const uuidForLink = isOrderPickupEvent(event) ? event.linkedEvent?.uuid : event.uuid;
const displayEventLink =
fixUrl(eventLink ?? '') || (uuidForLink && `https://acmucsd.com/events/${uuidForLink}`) || '';
const isUpcomingEvent = new Date(start) > new Date();

return (
<>
<div className={styles.image}>
{inModal && (
<button type="submit" aria-label="Close" className={styles.close}>
<CloseIcon aria-hidden className={styles.closeIcon} />
</button>
)}
{pointValue && <PointsDisplay points={pointValue} attended={attended} />}
<Image src={displayCover} alt="Event Cover Image" style={{ objectFit: 'cover' }} fill />
</div>
<div className={styles.contents}>
<div className={styles.header}>
<div className={styles.eventDetails}>
<CommunityLogo community={committee ?? 'General'} size={100} />
<div>
<Typography
className={styles.eventTitle}
variant="title/large"
style={{ fontWeight: 700 }}
>
{title}
</Typography>
<Typography
className={styles.eventInfo}
variant="title/medium"
suppressHydrationWarning
>
{formatEventDate(start, end, true)}
</Typography>
<Typography className={styles.eventInfo} variant="title/medium">
{location}
</Typography>
</div>
</div>

{isUpcomingEvent && !isOrderPickupEvent(event) ? <CalendarButtons event={event} /> : null}
</div>

<Typography variant="body/medium" style={{ wordBreak: 'break-word' }}>
{description}
</Typography>
{displayEventLink && (
<Link className={styles.link} href={displayEventLink}>
<div style={{ width: 11 }}>
<LinkIcon aria-hidden />
</div>
<Typography
variant="body/medium"
style={{ color: 'var(--theme-primary-2)', wordBreak: 'break-all' }}
>
{displayEventLink}
</Typography>
</Link>
)}
</div>
</>
);
};

export default EventDetail;
68 changes: 3 additions & 65 deletions src/components/events/EventModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { CommunityLogo, Modal, Typography } from '@/components/common';
import CalendarButtons from '@/components/events/CalendarButtons';
import PointsDisplay from '@/components/events/PointsDisplay';
import { Modal } from '@/components/common';
import EventDetail from '@/components/events/EventDetail';
import { PublicEvent } from '@/lib/types/apiResponses';
import { fixUrl, formatEventDate } from '@/lib/utils';
import CloseIcon from '@/public/assets/icons/close-icon.svg';
import LinkIcon from '@/public/assets/icons/link.svg';
import Image from 'next/image';
import Link from 'next/link';
import styles from './style.module.scss';

interface EventModalProps {
open: boolean;
Expand All @@ -17,64 +10,9 @@ interface EventModalProps {
}

const EventModal = ({ open, attended, event, onClose }: EventModalProps) => {
const { cover, title, start, end, location, description, eventLink } = event;

const displayCover = cover || '/assets/graphics/store/hero-photo.jpg';
const displayEventLink = fixUrl(eventLink) || `https://acmucsd.com/events/${event.uuid}`;
const isUpcomingEvent = new Date(start) > new Date();

return (
<Modal open={open} onClose={onClose} bottomSheet>
<div className={styles.image}>
<button type="submit" aria-label="Close" className={styles.close}>
<CloseIcon aria-hidden className={styles.closeIcon} />
</button>
<PointsDisplay points={event.pointValue} attended={attended} />
<Image src={displayCover} alt="Event Cover Image" style={{ objectFit: 'cover' }} fill />
</div>
<div className={styles.contents}>
<div className={styles.header}>
<div className={styles.eventDetails}>
<CommunityLogo community={event.committee} size={100} />
<div>
<Typography
className={styles.eventTitle}
variant="title/large"
style={{ fontWeight: 700 }}
>
{title}
</Typography>
<Typography
className={styles.eventInfo}
variant="title/medium"
suppressHydrationWarning
>
{formatEventDate(start, end, true)}
</Typography>
<Typography className={styles.eventInfo} variant="title/medium">
{location}
</Typography>
</div>
</div>

{isUpcomingEvent ? <CalendarButtons event={event} /> : null}
</div>

<Typography variant="body/medium" style={{ wordBreak: 'break-word' }}>
{description}
</Typography>
<Link className={styles.link} href={displayEventLink}>
<div style={{ width: 11 }}>
<LinkIcon role="link" />
</div>
<Typography
variant="body/medium"
style={{ color: 'var(--theme-primary-2)', wordBreak: 'break-all' }}
>
{displayEventLink}
</Typography>
</Link>
</div>
<EventDetail event={event} attended={attended} />
</Modal>
);
};
Expand Down
Loading