Skip to content
4 changes: 3 additions & 1 deletion app/(main)/request/CartPage.module.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
.itemsCard {
width: 36.0625rem;
width: 100%;
min-width: 36.0625rem;
height: auto;
background: #fff;
filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.05));
border-radius: 0.9375rem;
margin-bottom: 1rem;
}

.itemsCardHeader {
Expand Down
35 changes: 22 additions & 13 deletions app/(main)/request/[storeId]/cart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Breadcrumbs from '@/app/(main)/components/Breadcrumbs';
import Link from 'next/link';
import TicketDestStoreDropdown from '@/app/(main)/components/TicketDestStoreDropdown';
import { Store } from '@/app/types/store';
import AddOutOfStockToCartForm from '@/app/(main)/request/components/AddOutOfStockToCartForm';

export default async function CartPage({
params,
Expand Down Expand Up @@ -70,6 +71,10 @@ export default async function CartPage({
<h2>0 in-stock · 0 out-of-stock</h2>
</div>
</div>
<div>
<h2>Out-of-Stock Request</h2>
<AddOutOfStockToCartForm storeId={storeId} />
</div>
</div>
);
}
Expand Down Expand Up @@ -115,18 +120,6 @@ export default async function CartPage({
}}
/>
<h1>Cart</h1>
{hasItems ? (
<div>
<p>Ticket Destination Store: </p>
<TicketDestStoreDropdown
ticketId={ticket.ticket_id}
currentDestStore={(currentDestStore as Store) || null}
destStoreOptions={(destStoreOptions ?? []).map((store) => ({
store,
}))}
/>
</div>
) : null}
{showSuccess && (
<div>
<p>Ticket submitted successfully!</p>
Expand All @@ -135,7 +128,23 @@ export default async function CartPage({
)}
<div>
<TicketItemsList ticketId={ticket.ticket_id} />
{hasItems ? <SubmitTicketButton ticketId={ticket.ticket_id} /> : null}
<div>
<h2>Out-of-Stock Request</h2>
<AddOutOfStockToCartForm storeId={storeId} />
</div>
{hasItems ? (
<div>
<p>Ticket Destination Store: </p>
<TicketDestStoreDropdown
ticketId={ticket.ticket_id}
currentDestStore={(currentDestStore as Store) || null}
destStoreOptions={(destStoreOptions ?? []).map((store) => ({
store,
}))}
/>
<SubmitTicketButton ticketId={ticket.ticket_id} />
</div>
) : null}
</div>
</div>
);
Expand Down
3 changes: 0 additions & 3 deletions app/(main)/request/[storeId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import ItemCard from '@/app/(main)/components/ItemCard';
import ItemSearch from '@/app/(main)/components/ItemSearch';
import Breadcrumbs from '@/app/(main)/components/Breadcrumbs';
import Link from 'next/link';
import AddOutOfStockToCartForm from '@/app/(main)/request/components/AddOutOfStockToCartForm';
import styles from '@/app/(main)/request/Cart.module.css';
import Image from 'next/image';
import pinIcon from '@/public/pin-icon.svg';
Expand Down Expand Up @@ -152,8 +151,6 @@ export default async function RequestStorePage({
})) || []
}
/>
<h2>Out-of-Stock Request</h2>
<AddOutOfStockToCartForm storeId={storeId} />
<h2>In-Stock Items</h2>
{items && items.length > 0 ? (
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-5">
Expand Down
18 changes: 18 additions & 0 deletions app/(main)/request/all/Accordion.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.accordionSpacing {
margin-bottom: 1rem;
}

.accordionBody {
background-color: transparent;
border: none;
}

.accordionHeader :global(.accordion-button) {
box-shadow: none;
border: none;
}

.accordionBodySpacing {
padding-left: 0;
padding-right: 0;
}
80 changes: 52 additions & 28 deletions app/(main)/request/all/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { createClient } from '@/app/lib/supabase/server-client';
import TicketItemsList from '@/app/(main)/components/TicketItemsList';
import SubmitTicketButton from '@/app/(main)/request/components/SubmitTicketButton';
import Link from 'next/link';
import styles from '@/app/(main)/request/CartPage.module.css';
import Accordion from 'react-bootstrap/Accordion';
import AccordionBody from 'react-bootstrap/AccordionBody';
import AccordionHeader from 'react-bootstrap/AccordionHeader';
import AccordionItem from 'react-bootstrap/AccordionItem';
import Breadcrumbs from '@/app/(main)/components/Breadcrumbs';
import TicketDestStoreDropdown from '@/app/(main)/components/TicketDestStoreDropdown';
import accordionStyles from '@/app/(main)/request/all/Accordion.module.css';
import AddOutOfStockToCartForm from '@/app/(main)/request/components/AddOutOfStockToCartForm';

type DraftTicket = {
ticket_id: string;
Expand All @@ -17,13 +19,7 @@ type DraftTicket = {
}[];
};

export default async function AllCartsPage({
searchParams,
}: {
searchParams: Promise<{ submitted?: string; ticketId?: string }>;
}) {
const { submitted, ticketId } = await searchParams;
const showSuccess = submitted === '1' && !!ticketId;
export default async function AllCartsPage() {
const supabase = await createClient();

// Get the current user
Expand All @@ -38,7 +34,7 @@ export default async function AllCartsPage({
// Fetch stores
const { data: stores, error: storesError } = await supabase
.from('stores')
.select('store_id, name')
.select('store_id, name, street_address')
.order('name');

if (storesError || !stores) {
Expand Down Expand Up @@ -69,9 +65,14 @@ export default async function AllCartsPage({
{sortedStores.map((store) => {
return (
<Accordion key={store.store_id}>
<AccordionItem eventKey={store.store_id}>
<AccordionHeader>{store.name}</AccordionHeader>
<AccordionBody>
<AccordionItem
eventKey={store.store_id}
className={`${accordionStyles.accordionSpacing} ${accordionStyles.accordionBody}`}
>
<AccordionHeader className={accordionStyles.accordionHeader}>
{store.name}
</AccordionHeader>
<AccordionBody className={accordionStyles.accordionBodySpacing}>
<div className={styles.itemsCard}>
<div className={styles.itemsCardHeader}>
<h1>ITEMS</h1>
Expand Down Expand Up @@ -116,29 +117,52 @@ export default async function AllCartsPage({

return (
<Accordion key={store.store_id}>
<AccordionItem eventKey={store.store_id}>
<AccordionHeader>{store.name}</AccordionHeader>
<AccordionBody>
{showSuccess && (
<div>
<p>Ticket submitted successfully!</p>
<Link href={`/outgoing-tickets/${ticketId}`}>
Go to ticket
</Link>
</div>
)}
<AccordionItem
eventKey={store.store_id}
className={`${accordionStyles.accordionSpacing} ${accordionStyles.accordionBody}`}
>
<AccordionHeader className={accordionStyles.accordionHeader}>
{store.name}
</AccordionHeader>
<AccordionBody className={accordionStyles.accordionBodySpacing}>
{draftTicket ? (
<div>
<TicketItemsList ticketId={draftTicket.ticket_id} />
<div>
<h3>Out-of-Stock Request</h3>
<AddOutOfStockToCartForm storeId={store.store_id} />
</div>
{draftTicket.ticket_items[0].count > 0 ? (
<SubmitTicketButton ticketId={draftTicket.ticket_id} />
<div>
<p>Ticket Destination Store: </p>
<TicketDestStoreDropdown
ticketId={draftTicket.ticket_id}
currentDestStore={store.store_id}
destStoreOptions={stores
.filter((s) => s.store_id !== store.store_id)
.map((s) => ({
store: {
store_id: s.store_id,
name: s.name,
street_address: s.street_address,
},
}))}
/>
<SubmitTicketButton ticketId={draftTicket.ticket_id} />
</div>
) : null}
</div>
) : (
<div className={styles.itemsCard}>
<div className={styles.itemsCardHeader}>
<h1>ITEMS</h1>
<h2>0 in-stock · 0 out-of-stock</h2>
<div>
<div className={styles.itemsCard}>
<div className={styles.itemsCardHeader}>
<h1>ITEMS</h1>
<h2>0 in-stock · 0 out-of-stock</h2>
</div>
</div>
<div>
<h3>Out-of-Stock Request</h3>
<AddOutOfStockToCartForm storeId={store.store_id} />
</div>
</div>
)}
Expand Down
15 changes: 9 additions & 6 deletions app/(main)/request/all/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { createClient } from '@/app/lib/supabase/server-client';
import ItemSearch from '@/app/(main)/components/ItemSearch';
import ItemCard from '@/app/(main)/components/ItemCard';
import Link from 'next/link';
import AddOutOfStockToCartForm from '@/app/(main)/request/components/AddOutOfStockToCartForm';
import Accordion from 'react-bootstrap/Accordion';
import AccordionBody from 'react-bootstrap/AccordionBody';
import AccordionHeader from 'react-bootstrap/AccordionHeader';
Expand All @@ -11,6 +10,7 @@ import Breadcrumbs from '@/app/(main)/components/Breadcrumbs';
import styles from '@/app/(main)/request/Cart.module.css';
import Image from 'next/image';
import cartIcon from '@/public/cart-icon.svg';
import accordionStyles from '@/app/(main)/request/all/Accordion.module.css';

type SearchParams = {
query?: string;
Expand Down Expand Up @@ -169,11 +169,14 @@ export default async function RequestAllStoresPage({
const storeItems = itemsByStore.get(store.store_id) || [];
return (
<Accordion key={store.store_id}>
<AccordionItem eventKey={store.store_id}>
<AccordionHeader>{store.name}</AccordionHeader>
<AccordionBody>
<h3>Out-of-Stock Request</h3>
<AddOutOfStockToCartForm storeId={store.store_id} />
<AccordionItem
eventKey={store.store_id}
className={`${accordionStyles.accordionSpacing} ${accordionStyles.accordionBody}`}
>
<AccordionHeader className={accordionStyles.accordionHeader}>
{store.name}
</AccordionHeader>
<AccordionBody className={accordionStyles.accordionBodySpacing}>
{storeItems.length > 0 ? (
<div>
<h3>In-Stock Items</h3>
Expand Down
14 changes: 1 addition & 13 deletions app/(main)/request/components/SubmitTicketButton.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
'use client';
import { useState, useTransition } from 'react';
import { updateTicketStatus } from '@/app/actions/ticket';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';

export default function SubmitTicketButton({ ticketId }: { ticketId: string }) {
const [isPending, startTransition] = useTransition();
const [error, setError] = useState<string | null>(null);
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();

const handleSubmit = async () => {
setError(null);
startTransition(async () => {
const result = await updateTicketStatus('requested', ticketId);
if (result.success) {
const params = new URLSearchParams(searchParams?.toString() || '');
params.set('submitted', '1');
params.set('ticketId', ticketId);
router.replace(`${pathname}?${params.toString()}`);
} else {
setError(result.error || 'Failed to submit ticket.');
}
if (!result.success) setError(result.error || 'Failed to submit ticket.');
});
};

Expand Down
13 changes: 8 additions & 5 deletions app/actions/ticket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ export async function addToCart(
return { success: false, data: null, error: itemError.message };
}

return { success: true, data: ticketItem };
}
revalidatePath(`/request/${storeId}/cart`);
revalidatePath(`/request/all/cart`);

// If description is provided
if (description) {
return { success: true, data: ticketItem };
} else if (description) {
// Create a ticket item in ticket_items
const { data: ticketItem, error: itemError } = await supabase
.from('ticket_items')
Expand All @@ -262,10 +262,13 @@ export async function addToCart(
return { success: false, data: null, error: itemError.message };
}

revalidatePath(`/request/${storeId}/cart`);
revalidatePath(`/request/all/cart`);

return { success: true, data: ticketItem };
}

return { success: true, data: ticket };
return { success: true, data: null };
}

export async function updateTicketDestStore(
Expand Down
Loading