Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…i-v2 into nikhil/filter-pickup-events

merging from main
  • Loading branch information
nik-dange committed May 5, 2024
2 parents c4c6726 + 8219c00 commit 70fbb79
Show file tree
Hide file tree
Showing 21 changed files with 480 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"cookies-next": "^2.1.1",
"cypress": "13.6.2",
"ics": "^3.7.2",
"jszip": "^3.10.1",
"luxon": "^3.3.0",
"next": "^13.2.5-canary.30",
"next-pwa": "^5.6.0",
Expand Down
46 changes: 46 additions & 0 deletions src/components/admin/Resume/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { GifSafeImage, Typography } from '@/components/common';
import { config } from '@/lib';
import { PublicResume } from '@/lib/types/apiResponses';
import { getFileName, getProfilePicture } from '@/lib/utils';
import Link from 'next/link';
import { BsDownload } from 'react-icons/bs';
import styles from './style.module.scss';

interface ResumeProps {
resume: PublicResume;
}

const Resume = ({ resume }: ResumeProps) => {
const fileName = getFileName(resume.url, 'resume.pdf');

return (
<div className={styles.wrapper}>
{resume.user ? (
<Link href={`${config.userProfileRoute}${resume.user.handle}`} className={styles.user}>
<GifSafeImage
src={getProfilePicture(resume.user)}
width={48}
height={48}
alt={`Profile picture for ${resume.user.firstName} ${resume.user.lastName}`}
className={styles.image}
/>
<Typography variant="label/large" className={styles.name}>
{resume.user.firstName} {resume.user.lastName}
</Typography>
<p className={styles.info}>
{resume.user.major} ({resume.user.graduationYear})
</p>
</Link>
) : null}
<Link href={resume.url} className={styles.resume}>
<BsDownload className={styles.image} />
<p className={styles.name}>{fileName}</p>
<p className={styles.info}>
Uploaded {new Date(resume.lastUpdated).toLocaleDateString('en-US', { dateStyle: 'full' })}
</p>
</Link>
</div>
);
};

export default Resume;
73 changes: 73 additions & 0 deletions src/components/admin/Resume/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@use 'src/styles/vars.scss' as vars;

.wrapper {
background-color: var(--theme-elevated-background);
border: 1px solid var(--theme-elevated-stroke);
border-radius: 0.5rem;
display: flex;
gap: 1rem;
padding: 1rem;
word-break: break-word;

@media (max-width: vars.$breakpoint-md) {
flex-direction: column;
gap: 2rem;
}

.user,
.resume {
align-items: center;
display: grid;
gap: 0.5rem 1rem;
grid-template-areas:
'image name'
'image info';
grid-template-columns: auto 1fr;

.image {
grid-area: image;
}

.name {
grid-area: name;
}

&:hover .name {
text-decoration: underline;
}

.info {
grid-area: info;
}
}

.user {
flex: 1 0 0;

.image {
border-radius: 5rem;
object-fit: contain;
}
}

.resume {
flex: 1.5 0 0;

.image {
height: 1.5rem;
width: 1.5rem;

@media (max-width: vars.$breakpoint-md) {
width: 3rem;
}
}

.name {
color: var(--theme-blue-text-button);
}

.info {
color: var(--theme-text-on-background-2);
}
}
}
14 changes: 14 additions & 0 deletions src/components/admin/Resume/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type Styles = {
image: string;
info: string;
name: string;
resume: string;
user: string;
wrapper: string;
};

export type ClassNames = keyof Styles;

declare const styles: Styles;

export default styles;
23 changes: 14 additions & 9 deletions src/components/events/EventBadges/style.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,35 @@
animation: pulse 1s ease-in-out infinite alternate;

@keyframes pulse {
0% { opacity: 0 }
100% {opacity: 1 }
0% {
opacity: 0;
}

100% {
opacity: 1;
}
}
}

&::before {
animation: pulse2 2s ease-out forwards infinite;
animation: pulse2 2s ease-out reverse infinite;
border: 2px solid vars.$danger-1;
border-radius: 5px;
content: '';
position: absolute;

@keyframes pulse2 {
0% {
filter: blur(0);
inset: 0;
opacity: 1;
}

100% {
filter: blur(2px);
inset: -0.75rem;
opacity: 0;
}

100% {
filter: blur(0);
inset: 0;
opacity: 1;
}
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/store/CollectionSlider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import ItemCard from '@/components/store/ItemCard';
import StoreEditButton from '@/components/store/StoreEditButton';
import { config } from '@/lib';
import { PublicMerchItem } from '@/lib/types/apiResponses';
import { getDefaultMerchItemPhoto } from '@/lib/utils';
import Link from 'next/link';
import styles from './style.module.scss';

Expand Down Expand Up @@ -40,7 +39,9 @@ const CollectionSlider = ({
.map(item => (
<ItemCard
className={styles.card}
image={getDefaultMerchItemPhoto(item)}
images={[...item.merchPhotos]
.sort((a, b) => a.position - b.position)
.map(photo => photo.uploadedPhoto)}
title={item.itemName}
href={`${config.store.itemRoute}${item.uuid}`}
cost={item.options[0]?.price ?? 0}
Expand Down
10 changes: 7 additions & 3 deletions src/components/store/ItemCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import Diamonds from '@/components/store/Diamonds';
import NoImage from '@/public/assets/graphics/cat404.png';
import Image from 'next/image';
import Link from 'next/link';
import { PropsWithChildren } from 'react';
import styles from './style.module.scss';

interface CommonOptions {
image: string;
images: string[];
title: string;
href: string;
className?: string;
Expand All @@ -29,18 +30,21 @@ type ItemCardProps = (StoreItemOptions | CollectionOptions) & CommonOptions;
* - a collection with a `description`.
*/
const ItemCard = ({
image,
images,
title,
href,
className,
children,
...props
}: PropsWithChildren<ItemCardProps>) => {
const [first = NoImage, second = first] = images;

return (
<article className={`${styles.itemCard} ${className}`}>
<Link href={href} className={styles.linkWrapper}>
<div className={styles.imageWrapper}>
<Image src={image} alt={title} fill />
<Image className={styles.first} src={first} alt={title} fill />
<Image src={second} alt="" aria-hidden fill />
</div>
<div className={styles.details}>
<p className={styles.title}>{title}</p>
Expand Down
10 changes: 10 additions & 0 deletions src/components/store/ItemCard/style.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
img {
object-fit: cover;
}

.first {
transition: opacity 0.5s;
z-index: 1;
}
}

&:hover .imageWrapper .first {
opacity: 0;
}

.details {
Expand Down Expand Up @@ -63,5 +72,6 @@
position: absolute;
right: 0.5rem;
top: 0.5rem;
z-index: 2;
}
}
1 change: 1 addition & 0 deletions src/components/store/ItemCard/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type Styles = {
cost: string;
details: string;
first: string;
icons: string;
imageWrapper: string;
itemCard: string;
Expand Down
7 changes: 5 additions & 2 deletions src/components/store/OrderCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const OrderCard = ({ order, futurePickupEvents }: OrderCardProps) => {
const [pickupEvent, setPickupEvent] = useState<PublicOrderPickupEvent>(order.pickupEvent);
const [orderStatus, setOrderStatus] = useState<OrderStatus>(order.status);
const orderOpen = open && orderData !== null;
const [statusName, setStatusName] = useState<string>(orderStatusName[orderStatus]);

useEffect(() => {
if (open && orderData === null) {
Expand All @@ -57,8 +58,10 @@ const OrderCard = ({ order, futurePickupEvents }: OrderCardProps) => {
reportError('Error loading order!', e);
setOrderData(null);
});
} else if (open) {
setStatusName(orderStatusName[orderStatus]);
}
}, [open, order.uuid, orderData]);
}, [open, order.uuid, orderData, pickupEvent, orderStatus]);

const cancelOrder = async () => {
await StoreManager.cancelMerchOrder(order.uuid);
Expand All @@ -68,10 +71,10 @@ const OrderCard = ({ order, futurePickupEvents }: OrderCardProps) => {
const rescheduleOrderPickup = async (pickup: PublicOrderPickupEvent) => {
await StoreManager.rescheduleOrderPickup(order.uuid, pickup.uuid);
setPickupEvent(pickup);
setOrderStatus(OrderStatus.PLACED);
};

const statusColor = orderStatusColor[orderStatus];
const statusName = orderStatusName[orderStatus];

return (
<div className={styles.card}>
Expand Down
6 changes: 5 additions & 1 deletion src/components/store/OrderSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ const isOrderActionable = (status: OrderStatus, pickupEvent: PublicOrderPickupEv
const now = new Date();
const eventStart = new Date(pickupEvent.start);
eventStart.setDate(eventStart.getDate() - 2);
if (now > eventStart) {
if (
now > eventStart &&
status !== OrderStatus.PICKUP_MISSED &&
status !== OrderStatus.PICKUP_CANCELLED
) {
return false;
}
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/components/store/PickupEventDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const PickupEventDetail = ({ pickupEvent }: PickupEventDetailProps) => {
{title}
</Typography>
<Typography variant="h2/regular" className={styles.title} suppressHydrationWarning>
{formatEventDate(start, end)}
{formatEventDate(start, end, true)}
</Typography>
{hasLinkedEvent ? (
<Typography variant="h3/regular">{linkedEvent?.location}</Typography>
Expand Down
20 changes: 11 additions & 9 deletions src/components/store/PickupEventPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ const PickupEventPicker = ({ events, eventIndex, setEventIndex, active }: EventP
className={styles.slider}
style={{ transform: `translateX(calc(-1 * var(--width) * ${eventIndex}))` }}
>
{events.map(event => (
<EventCard
key={event.uuid}
event={event}
attended={false}
borderless
showYear={false}
/>
))}
{events
.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())
.map(event => (
<EventCard
key={event.uuid}
event={event}
attended={false}
borderless
showYear={false}
/>
))}
</div>
) : (
<div className={styles.noEvents}>
Expand Down
26 changes: 22 additions & 4 deletions src/lib/api/ResumeAPI.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { config } from '@/lib';
import type { UUID } from '@/lib/types';
import { PatchResumeRequest } from '@/lib/types/apiRequests';
import type {
PatchResumeResponse,
PublicResume,
UpdateResumeResponse,
import {
GetVisibleResumesResponse,
type PatchResumeResponse,
type PublicResume,
type UpdateResumeResponse,
} from '@/lib/types/apiResponses';
import axios from 'axios';

Expand Down Expand Up @@ -76,3 +77,20 @@ export const deleteResume = async (token: string, uuid: UUID): Promise<void> =>
},
});
};

/**
* Get all visible resumes
* @param token Authorization bearer token. User needs to be admin or
* sponsorship manager
*/
export const getResumes = async (token: string): Promise<PublicResume[]> => {
const requestUrl = `${config.api.baseUrl}${config.api.endpoints.resume}`;

const response = await axios.get<GetVisibleResumesResponse>(requestUrl, {
headers: {
Authorization: `Bearer ${token}`,
},
});

return response.data.resumes;
};
Loading

0 comments on commit 70fbb79

Please sign in to comment.