Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
96 changes: 96 additions & 0 deletions app/(main)/request/[storeId]/[storeItemId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { createClient } from '@/app/lib/supabase/server-client';
// exports server component RequestStoreItemPage
export default async function RequestStoreItemPage({
params,
}: {
params: Promise<{ storeId: string; storeItemId: string }>;
}) {
const { storeId, storeItemId } = await params; // page takes storeId and storeItemId as props

const supabase = await createClient();

// select store_item_id and quantity_available from store_items
// select name, description, and photo_url from inventory_items
// select subcategories.name and categories.name
const { data: storeItem, error: itemError } = await supabase
.from('store_items')
.select(
`
store_item_id,
quantity_available,
inventory_items (
name,
description,
photo_url,
subcategories (
name,
categories (
name
)
)
)
`
)
// match storeItemId
.eq('store_item_id', storeItemId)
.single();

if (itemError) {
console.error('Error fetching store item:', itemError);
return <div>Failed to load data.</div>;
}
// extract nested values: name description, category, subcategory
const inv = storeItem.inventory_items?.[0];
const subcat = inv?.subcategories?.[0];
const category = subcat?.categories?.[0];

return (
<div
style={{
border: '1px solid #ccc',
padding: '1rem',
borderRadius: '8px',
width: '350px',
}}
>
<h1>Request Item Details</h1>
{/* display inventory item name */}
<h2>{inv?.name}</h2>

{inv?.photo_url && (
<img
src={inv.photo_url}
alt={inv?.name}
width="200"
style={{ borderRadius: '6px', marginBottom: '1rem' }}
/>
)}

{/* Display inventory item description */}
<p>
<strong>Description:</strong>{' '}
{inv?.description ?? 'No description available'}
</p>

{/* display category name */}
<p>
<strong>Category:</strong> {category?.name ?? 'None'}
</p>

{/* display subcategory name */}
<p>
<strong>Subcategory:</strong> {subcat?.name ?? 'None'}
</p>

{/* display quantity available */}
<p>
<strong>Quantity Available:</strong>{' '}
{storeItem.quantity_available ?? 'Unknown'}
</p>

<a href={`/request/${storeId}`}>
<button>--Back--</button>
</a>
</div>
);
}
88 changes: 88 additions & 0 deletions app/(main)/request/[storeId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { createClient } from '@/app/lib/supabase/server-client';
import RequestStoreItemCard from '@/app/(main)/request/components/RequestStoreItemCard';

// server component exported
export default async function RequestStorePage({
params,
}: {
// takes in storeId as prop
params: Promise<{ storeId: string }>;
}) {
const { storeId } = await params;

const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();

//fetch store's entry in stores table (filters on store_id)
const { data: store } = await supabase
.from('stores')
.select('*')
.eq('store_id', storeId)
.single();

// get all non-hidden store items for store
// fetch nested inventory + category data
const { data: storeItems } = await supabase
.from('store_items')
.select(
`
store_item_id,
inventory_items (
name,
photo_url,
subcategories (
name,
categories (
name
)
)
)
`
)
.eq('store_id', storeId)
.eq('hidden', false);

return (
// display store's name and street address
<div>
<h1>Store – {store.name}</h1>
<h2>Street Address: {store.street_address}</h2>

<h2 style={{ marginTop: '2rem' }}>Available Items</h2>
{/* iterates through store items */}
{storeItems && storeItems.length > 0 ? (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem' }}>
{storeItems.map((item) => {
const inv = item.inventory_items?.[0];
const subcat = inv?.subcategories?.[0];
const category = subcat?.categories?.[0];

return (
<a
key={item.store_item_id}
// clicking card routes to /request/[storeId]/[storeItemId]
href={`/request/${storeId}/${item.store_item_id}`}
style={{ textDecoration: 'none', color: 'inherit' }}
>
{/* pass each store item to a RequestItemCard component */}
<RequestStoreItemCard
name={inv?.name}
subcategoryName={subcat?.name}
categoryName={category?.name}
/>
</a>
);
})}
</div>
) : (
<h3>N/A. No items to display.</h3>
)}

<a href="./">
<button>--Back--</button>
</a>
</div>
);
}
25 changes: 25 additions & 0 deletions app/(main)/request/components/RequestStoreItemCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export default function RequestStoreItemCard({
name,
subcategoryName,
categoryName,
}: {
name: string | undefined;
subcategoryName: string | undefined;
categoryName: string | undefined;
}) {
return (
<div
style={{
border: '1px solid #ccc',
padding: '1rem',
borderRadius: '8px',
width: '250px',
cursor: 'pointer',
}}
>
<h3>{name}</h3>
<p>Category: {categoryName}</p>
<p>Subcategory: {subcategoryName}</p>
</div>
);
}