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

fulfill #244

Merged
merged 24 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3c4be9a
Add fulfill button
SheepTester Apr 29, 2024
f21f8f1
Remove Fulfill view and move fulfill buttons to prepare view
SheepTester Apr 29, 2024
b39c58e
Do not show fulfill button if it's already fulfilled
SheepTester Apr 29, 2024
6fd90be
make order status component
SheepTester Apr 29, 2024
85e3484
hide fulfill button if pickup event hasnt started yet
SheepTester Apr 29, 2024
4aa2379
Apparently partially fulfilled means they are missing some items
SheepTester Apr 29, 2024
7629d92
move order row to separate component
SheepTester Apr 30, 2024
f93f5d1
fulfill selected
SheepTester May 4, 2024
31432e7
Merge branch 'main' into sean/fulfill
SheepTester May 5, 2024
070291d
fix type errors
SheepTester May 5, 2024
4550fa0
Merge remote-tracking branch 'origin/main' into sean/fulfill
SheepTester May 14, 2024
2d5b880
always show fulfilled items
SheepTester May 14, 2024
36c1567
sorting things and other misc changes:
SheepTester May 14, 2024
dd810b1
exclude fulfilled items from item breakdown
SheepTester May 14, 2024
26fe66c
default checkboxes to unchecked
SheepTester May 14, 2024
45772bf
fix fulfilling selected. always indicate whether an item was fulfilled
SheepTester May 14, 2024
3f71919
Show fulfilled badges
SheepTester May 14, 2024
a664aea
Labels back to emoji, have checkbox select all of an entire variant a…
SheepTester Aug 19, 2024
cd164cb
Merge branch 'main' into sean/fulfill
SheepTester Aug 19, 2024
efc08fb
Display "fulfilled" on fulfilled items in fulfilled/partially fulfill…
SheepTester Aug 19, 2024
505140c
Make "picked up" badge green
SheepTester Aug 19, 2024
a5a1e96
Merge branch 'main' into sean/fulfill
SheepTester Aug 20, 2024
95d304f
Address feedback
SheepTester Aug 21, 2024
d7bd9d1
Merge branch 'sean/fulfill' of https://github.com/acmucsd/membership-…
SheepTester Aug 21, 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
90 changes: 90 additions & 0 deletions src/components/admin/store/PickupOrder/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Button, Typography } from '@/components/common';
import { OrderStatusIndicator } from '@/components/store';
import { StoreAPI } from '@/lib/api';
import { UUID } from '@/lib/types';
import { PublicOrderWithItems } from '@/lib/types/apiResponses';
import { OrderStatus } from '@/lib/types/enums';
import { getOrderItemQuantities, itemToString, reportError } from '@/lib/utils';
import { useState } from 'react';
import styles from './style.module.scss';

interface PickupOrderProps {
token: string;
canFulfill: boolean;
order: PublicOrderWithItems;
onOrderUpdate: (orders: PublicOrderWithItems) => void;
}

const PickupOrder = ({ token, canFulfill, order, onOrderUpdate }: PickupOrderProps) => {
const itemQuantities = getOrderItemQuantities(order.items);
const [unselected, setUnselected] = useState(new Set<UUID>());

return (
<tr className={styles.row}>
<td>
<Typography variant="h5/regular">{`${order.user.firstName} ${order.user.lastName}`}</Typography>
<OrderStatusIndicator orderStatus={order.status} />
{canFulfill ? (
<Button
size="small"
onClick={async () => {
try {
const items = order.items.filter(item => !unselected.has(item.uuid));
const newOrder = await StoreAPI.fulfillOrderPickup(token, order.uuid, items);
const itemUuids = items.map(item => item.uuid);
onOrderUpdate({
...newOrder,
items: order.items.map(item =>
itemUuids.includes(item.uuid) ? { ...item, fulfilled: true } : item
),
});
SheepTester marked this conversation as resolved.
Show resolved Hide resolved
} catch (error: unknown) {
reportError('Failed to fulfill order', error);
}
}}
>
Fulfill {unselected.size > 0 ? 'Selected' : 'All'}
</Button>
) : null}
</td>
<td>
<ul className={styles.itemList}>
{itemQuantities.map(item => {
return (
<li key={item.uuids[0]}>
<Typography variant="h5/regular">
{`${item.quantity} x ${itemToString(item)}`}{' '}
{(order.status === OrderStatus.FULFILLED ||
order.status === OrderStatus.PARTIALLY_FULFILLED) &&
!item.fulfilled ? (
<span className={styles.notFulfilled}>Not fulfilled</span>
) : null}
</Typography>
{canFulfill
? item.uuids.map(uuid => (
<input
key={uuid}
type="checkbox"
checked={!unselected.has(uuid)}
onChange={e => {
const copy = new Set(unselected);
if (e.currentTarget.checked) {
copy.delete(uuid);
} else {
copy.add(uuid);
}
setUnselected(copy);
}}
/>
))
: null}
</li>
);
})}
</ul>
</td>
</tr>
);
};

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

.row {
border-top: 1px solid var(--theme-accent-line-2);

td {
padding: 1.5rem;
}

.itemList {
list-style-type: disc;

li {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: 10px;

.notFulfilled {
color: vars.$red;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type Styles = {
breakdown: string;
container: string;
table: string;
itemList: string;
notFulfilled: string;
row: string;
};

export type ClassNames = keyof Styles;
Expand Down
20 changes: 0 additions & 20 deletions src/components/admin/store/PickupOrdersFulfillDisplay/index.tsx

This file was deleted.

This file was deleted.

121 changes: 66 additions & 55 deletions src/components/admin/store/PickupOrdersPrepareDisplay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import PickupOrder from '@/components/admin/store/PickupOrder';
import { Typography } from '@/components/common';
import { PublicOrderItemWithQuantity, PublicOrderWithItems } from '@/lib/types/apiResponses';
import { getOrderItemQuantities } from '@/lib/utils';
import { PublicOrderWithItems } from '@/lib/types/apiResponses';
import { OrderStatus } from '@/lib/types/enums';
import { OrderItemQuantity, getOrderItemQuantities, itemToString } from '@/lib/utils';
import { useMemo } from 'react';
import styles from './style.module.scss';

interface PickupOrdersDisplayPrepareProps {
token: string;
canFulfill: boolean;
orders: PublicOrderWithItems[];
onOrderUpdate: (orders: PublicOrderWithItems[]) => void;
}

const itemToString = (item: PublicOrderItemWithQuantity): string => {
if (item.option.metadata !== null)
return `${item.option.item.itemName} (${item.option.metadata.type}: ${item.option.metadata.value})`;
return item.option.item.itemName;
};

const PickupOrdersPrepareDisplay = ({ orders }: PickupOrdersDisplayPrepareProps) => {
const itemBreakdown: PublicOrderItemWithQuantity[] = useMemo(() => {
const PickupOrdersPrepareDisplay = ({
token,
canFulfill,
orders,
onOrderUpdate,
}: PickupOrdersDisplayPrepareProps) => {
const itemBreakdown: OrderItemQuantity[] = useMemo(() => {
// Concatenate all items together into one large order to display the item breakdown.
const allItems = orders.flatMap(a => a.items);
return getOrderItemQuantities(allItems);
Expand All @@ -26,56 +30,63 @@ const PickupOrdersPrepareDisplay = ({ orders }: PickupOrdersDisplayPrepareProps)
<div className={styles.breakdown}>
<Typography variant="h3/bold">Item Breakdown</Typography>
<table className={styles.table}>
<th>
<Typography variant="h4/bold">Quantity</Typography>
</th>
<th>
<Typography variant="h4/bold">Item</Typography>
</th>
{itemBreakdown.map(item => {
return (
<tr key={item.uuid}>
<td>
<Typography variant="h5/regular">{item.quantity}</Typography>
</td>
<td>
<Typography variant="h5/regular">{itemToString(item)}</Typography>
</td>
</tr>
);
})}
<thead>
<tr>
<th>
<Typography variant="h4/bold">Quantity</Typography>
</th>
<th>
<Typography variant="h4/bold">Item</Typography>
</th>
</tr>
</thead>
<tbody>
{itemBreakdown.map(item => {
return (
<tr key={item.uuids[0]}>
<td>
<Typography variant="h5/regular">{item.quantity}</Typography>
</td>
<td>
<Typography variant="h5/regular">{itemToString(item)}</Typography>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
<div className={styles.breakdown}>
<Typography variant="h3/bold">User Breakdown</Typography>
<table className={styles.table}>
<th>
<Typography variant="h4/bold">User</Typography>
</th>
<th>
<Typography variant="h4/bold">Items</Typography>
</th>
{orders.map(order => {
const itemQuantities = getOrderItemQuantities(order.items);
return (
<tr key={order.uuid}>
<td>
<Typography variant="h5/regular">{`${order.user.firstName} ${order.user.lastName}`}</Typography>
</td>
<td>
<ul className={styles.itemList}>
{itemQuantities.map(item => (
<li key={item.uuid}>
<Typography variant="h5/regular">{`${item.quantity} x ${itemToString(
item
)}`}</Typography>
</li>
))}
</ul>
</td>
</tr>
);
})}
<thead>
<tr>
<th>
<Typography variant="h4/bold">User</Typography>
</th>
<th>
<Typography variant="h4/bold">Items</Typography>
</th>
</tr>
</thead>
<tbody>
{orders.map(order => (
<PickupOrder
canFulfill={canFulfill && order.status === OrderStatus.PLACED}
order={order}
onOrderUpdate={newOrder =>
onOrderUpdate(
orders.map(
(order): PublicOrderWithItems =>
order.uuid === newOrder.uuid ? newOrder : order
)
)
}
token={token}
key={order.uuid}
/>
))}
</tbody>
</table>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,7 @@
padding: 1.5rem;
}

tr {
tbody tr {
border-top: 1px solid var(--theme-accent-line-2);
}

tr:last-child td:first-child {
border-bottom-left-radius: 1rem;
}
}

.itemList {
list-style-type: disc;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export type Styles = {
breakdown: string;
container: string;
itemList: string;
table: string;
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/admin/store/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { PickupEventStatus } from '@/components/admin/store/PickupEventCard';
export { default as CollectionDetailsForm } from './DetailsForm/CollectionDetailsForm';
export { default as ItemDetailsForm } from './DetailsForm/ItemDetailsForm';
export { default as PickupEventCard } from './PickupEventCard';
export { default as PickupOrdersFulfillDisplay } from './PickupOrdersFulfillDisplay';
export { default as PickupOrder } from './PickupOrder';
export { default as PickupOrdersPrepareDisplay } from './PickupOrdersPrepareDisplay';
export { PickupEventStatus };
Loading
Loading