From f3f93785f8301a12c4f02f55b488fec096e700be Mon Sep 17 00:00:00 2001 From: joy-y-cheng Date: Sun, 17 May 2026 22:56:41 -0700 Subject: [PATCH 1/5] Make donation form, add store items form styles consistent --- app/(main)/components/DonationForm.module.css | 180 +----------------- .../components/LightweightDonationForm.tsx | 63 +++--- .../add/components/AddStoreItemSearch.tsx | 147 +++++++------- .../[storeId]/add/components/DonationForm.tsx | 51 +++-- .../add/components/StoreItemsDonationForm.tsx | 14 +- app/(main)/manage/[storeId]/add/page.tsx | 1 + app/globals.css | 31 ++- 7 files changed, 161 insertions(+), 326 deletions(-) diff --git a/app/(main)/components/DonationForm.module.css b/app/(main)/components/DonationForm.module.css index c63bf298..747b981f 100644 --- a/app/(main)/components/DonationForm.module.css +++ b/app/(main)/components/DonationForm.module.css @@ -1,192 +1,24 @@ -/* .formContainer:global(.container) { - width: 100%; - max-width: none; - margin: 0; - --bs-gutter-x: 0; - padding-block: 20px; - box-sizing: border-box; -} -.formContainer :global(.form-control), -.formContainer :global(.form-select), -.formContainer :global(.form-check-label), -.formContainer :global(.form-label) { - font-family: inherit; -} - -.formContainer :global(.form-control::placeholder) { - color: #a2a2a2; - opacity: 1; -} - -.formCard { - border: none; - border-radius: 5px; - padding: 0; -} - -.formCard :global(.card-body) { - padding: 40px; -} - -.formTitle1 { - font-size: 1.5rem; - line-height: 1.2; - font-weight: 600; - margin-bottom: 20px; -} - -.formTitle2 { - font-size: 1.5rem; - font-weight: 600; - margin-top: 12px; - margin-bottom: 0; -} - -.formBody { - display: flex; - flex-direction: column; - gap: 20px; -} - -.radioRow { - display: flex; - gap: 20px; - align-items: center; - flex-wrap: wrap; -} - -.twoColRow { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 20px; - align-items: start; -} - -@media (max-width: 1020px) { - .twoColRow { - grid-template-columns: 1fr; - } - - .formCard :global(.card-body) { - padding: 24px 20px; - } -} - -.fieldLabel { - margin-bottom: 5px; -} - -.businessFields { - display: flex; - flex-direction: column; - gap: 20px; -} - -.checkboxGroup { - display: flex; - flex-direction: column; - gap: 5px; -} - -.errorText { - color: red; - margin-top: 5px; - display: block; -} - -.submitButtonRow { - display: flex; - justify-content: flex-end; - margin-top: 20px; -} - -.submitButton { - display: inline-flex; - padding: 8px 40px; - justify-content: center; - align-items: center; - gap: 10px; - border: none; - border-radius: 5px; - background: #2d3748; - color: #fff; - font-weight: 400; - cursor: pointer; -} - -.submitButton:hover { - background: #4a5568; - transition: background 0.2s ease; -} - -.submitButton:active { - background: #1a202c; -} - -.receivingSiteGroup { - margin-bottom: 10px; -} - -.estimatedValueField { - max-width: 200px; -} */ - /* ── container reset (donation-specific) ── */ .formContainer:global(.container) { width: 100%; max-width: none; margin: 0; --bs-gutter-x: 0; - padding-block: 20px; + padding-block: 1.5rem; box-sizing: border-box; } -/* ── layout: body & rows ── */ -.formBody { - display: flex; - flex-direction: column; - gap: 20px; -} - -.radioRow { - display: flex; - gap: 20px; - align-items: center; - flex-wrap: wrap; -} - -.twoColRow { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 20px; - align-items: start; -} - -@media (max-width: 1020px) { - .twoColRow { - grid-template-columns: 1fr; - } -} - /* ── donation-specific field groups ── */ .businessFields { display: flex; flex-direction: column; - gap: 20px; + gap: 1.25rem; } .checkboxGroup { display: flex; flex-direction: column; - gap: 5px; -} - -.receivingSiteGroup { - margin-bottom: 10px; -} - -.estimatedValueField { - max-width: 200px; + gap: 0.25rem; } /* ── error & submit row ── */ @@ -195,9 +27,3 @@ margin-top: 5px; display: block; } - -.submitButtonRow { - display: flex; - justify-content: flex-end; - margin-top: 20px; -} diff --git a/app/(main)/home/donate/components/LightweightDonationForm.tsx b/app/(main)/home/donate/components/LightweightDonationForm.tsx index c19c412b..143a5e8b 100644 --- a/app/(main)/home/donate/components/LightweightDonationForm.tsx +++ b/app/(main)/home/donate/components/LightweightDonationForm.tsx @@ -4,7 +4,7 @@ import { forwardRef, useState } from 'react'; import { DonationInsert } from '@/app/types/donation'; import { useForm, useWatch, Controller } from 'react-hook-form'; import { PatternFormat, NumericFormat } from 'react-number-format'; -import { Form, Container, Card, Alert } from 'react-bootstrap'; +import { Form, Card, Alert } from 'react-bootstrap'; import type { FormControlProps } from 'react-bootstrap'; import { createDonation } from '@/app/actions/donation'; import styles from '@/app/(main)/components/DonationForm.module.css'; @@ -151,32 +151,27 @@ export default function LightweightDonationForm({ stores, user }: Props) { }; return ( - +
+

Record Gift-in-Kind

-
-
-

Store Information

- - Receiving site - - - {receivingSiteOptions.map((site) => ( - - ))} - - -
+ +

Store Information

+ + Receiving Site + + {receivingSiteOptions.map((site) => ( + + ))} + + -

Donor Information

+

Donor Information

-
+
{errors.donor_type && ( - + {errors.donor_type.message} - + )} {donorType && ( <> -
+
{donorType === 'individual' && ( @@ -287,7 +282,7 @@ export default function LightweightDonationForm({ stores, user }: Props) {
-
+
@@ -349,9 +344,9 @@ export default function LightweightDonationForm({ stores, user }: Props) { /> {errors.phone && ( - + {errors.phone.message} - + )}
@@ -382,11 +377,11 @@ export default function LightweightDonationForm({ stores, user }: Props) { )} -

Donation Information

+

Donation Information

- Estimated value (USD) + Estimated Value (USD) - Items donated + Items Donated -
+
@@ -459,12 +454,12 @@ export default function LightweightDonationForm({ stores, user }: Props) { {showSuccess && ( - Form submitted successfully! Thank you for your donation. + Form submitted successfully! )} - +
); } diff --git a/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx b/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx index 5c11e2c8..ae694f82 100644 --- a/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx +++ b/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx @@ -14,9 +14,8 @@ import AddInventoryItemForm, { Inputs, } from '@/app/(main)/manage/components/AddInventoryItemForm'; import { createItem } from '@/app/actions/inventory'; -import { Form, Container, Card } from 'react-bootstrap'; +import { Form, Card } from 'react-bootstrap'; import AddItemCard from '@/app/(main)/manage/[storeId]/add/components/AddItemCard'; -import donationStyles from '@/app/(main)/components/DonationForm.module.css'; import { ListGroup } from 'react-bootstrap'; type ItemWithNames = InventoryItem & { @@ -178,85 +177,81 @@ export default function AddStoreItemSearch({ }; return ( -
- - - -
- -
- setInventoryType('existing')} +
+ + +
+ +
+ setInventoryType('existing')} + /> + setInventoryType('new')} + /> +
+
+ {inventoryType == 'existing' && ( +
+
+ setSearchQuery(e.target.value)} /> - setInventoryType('new')} - /> -
- - {inventoryType == 'existing' && ( -
-
- setSearchQuery(e.target.value)} - /> -
- {results.length > 0 && ( - - {results?.map((item) => ( - handleSelect(item)} - > - {item.name} - - ))} - - )}
- )} - {inventoryType == 'new' && ( - - -
-
- -
-
-
- )} -
- - - + {item.name} + + ))} + + )} +
+ )} + {inventoryType == 'new' && ( + + +
+ +
+
+ )} +
+ + -

Selected Items

+

Selected Items

{fields.length > 0 ? (
{fields.map((field, idx) => ( diff --git a/app/(main)/manage/[storeId]/add/components/DonationForm.tsx b/app/(main)/manage/[storeId]/add/components/DonationForm.tsx index 46c5bfb2..1ab0b2d8 100644 --- a/app/(main)/manage/[storeId]/add/components/DonationForm.tsx +++ b/app/(main)/manage/[storeId]/add/components/DonationForm.tsx @@ -3,7 +3,7 @@ import { forwardRef } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { PatternFormat, NumericFormat } from 'react-number-format'; -import { Form, Container, Card } from 'react-bootstrap'; +import { Form, Card } from 'react-bootstrap'; import type { FormControlProps } from 'react-bootstrap'; import { CombinedFormData } from '@/app/(main)/manage/[storeId]/add/components/StoreItemsDonationForm'; import styles from '@/app/(main)/components/DonationForm.module.css'; @@ -29,14 +29,14 @@ export default function DonationForm({ } = useFormContext(); return ( - +
-

Donor Information

-
+
+

Donor Information

{/* Donor Type */} -
+
{errors.donor_type && ( - + {errors.donor_type.message} - + )} {donorType && ( <> {/* Name + Address (same row) */} -
+
{/* Conditional Name Field: Individual */} {donorType === 'individual' && ( - + Individual Name - + Business Name - + Business Contact Name {/* Street Address */} - + Donor Street Address {/* Email + Phone (same row) */} -
+
{/* Email */} - + Donor Email {/* Phone */} - + Donor Phone Number (Optional) {errors.phone && ( - + {errors.phone.message} - + )}
@@ -233,14 +233,11 @@ export default function DonationForm({ )} -

Donation Information

+

Donation Information

{/* Estimated Value */} - - + + Estimated value (USD) - - Items donated - + Items donated {showSubmitButton && ( -
+
@@ -316,6 +311,6 @@ export default function DonationForm({
- +
); } diff --git a/app/(main)/manage/[storeId]/add/components/StoreItemsDonationForm.tsx b/app/(main)/manage/[storeId]/add/components/StoreItemsDonationForm.tsx index 94780f39..11c5aa02 100644 --- a/app/(main)/manage/[storeId]/add/components/StoreItemsDonationForm.tsx +++ b/app/(main)/manage/[storeId]/add/components/StoreItemsDonationForm.tsx @@ -184,9 +184,11 @@ export default function StoreItemsDonationForm({ }; return (
-

Add Items

-
+
{/* add autofillitems connection pass in prop to storeitemsform */} - +
+ +
)} diff --git a/app/(main)/manage/[storeId]/add/page.tsx b/app/(main)/manage/[storeId]/add/page.tsx index 0468d003..2e3671bf 100644 --- a/app/(main)/manage/[storeId]/add/page.tsx +++ b/app/(main)/manage/[storeId]/add/page.tsx @@ -39,6 +39,7 @@ export default async function AddStoreItemsPage({ add: 'Add Store Items', }} /> +

Add Store Items

); diff --git a/app/globals.css b/app/globals.css index 6507e355..d184caf1 100644 --- a/app/globals.css +++ b/app/globals.css @@ -62,7 +62,13 @@ Table { } .main-container { - padding-top: calc(3rem + 3.875rem); + padding: calc(1.5rem + 3.875rem) 1.5rem 1.5rem 1.5rem; +} + +@media (min-width: 576px) { + .main-container { + padding: calc(3rem + 3.875rem) 3rem 3rem 3rem; + } } @media (min-width: 992px) { @@ -96,7 +102,7 @@ Table { padding: 1.5rem; } -@media (min-width: 768px) { +@media (min-width: 576px) { .form-card .card-body { padding: 3rem; } @@ -120,6 +126,12 @@ Table { } /* ── section headings ── */ +.form-title { + font-size: 1.5rem; + font-weight: 600; + margin-bottom: 0; +} + .form-title-1 { font-size: 1.5rem; line-height: 1.2; @@ -223,6 +235,12 @@ Table { gap: 1.25rem; } +.content-body { + gap: 1.25rem; + display: flex; + flex-direction: column; +} + .radio-row { display: flex; gap: 2rem; @@ -235,13 +253,14 @@ Table { .two-col-row { display: grid; - grid-template-columns: 1fr 1fr; - gap: 16px; + grid-template-columns: 1fr; + gap: 1.25rem; } -@media (max-width: 600px) { +@media (min-width: 768px) { .two-col-row { - grid-template-columns: 1fr; + display: grid; + grid-template-columns: 1fr 1fr; } } From cfea6a93cbfc390e02837da7458f5552bc6c0abd Mon Sep 17 00:00:00 2001 From: joy-y-cheng Date: Sun, 17 May 2026 23:40:28 -0700 Subject: [PATCH 2/5] Update profile form styling --- .../administration/members/[userId]/page.tsx | 64 ++++++++++--------- app/(main)/faq/page.tsx | 2 +- .../add/components/AddStoreItemSearch.tsx | 51 +++++++-------- .../profile/components/ProfileForm.module.css | 21 ++---- app/(main)/profile/components/ProfileForm.tsx | 8 +-- .../profile/components/UpdatePasswordForm.tsx | 2 +- app/(main)/profile/page.tsx | 14 ++-- app/globals.css | 2 +- 8 files changed, 80 insertions(+), 84 deletions(-) diff --git a/app/(main)/administration/members/[userId]/page.tsx b/app/(main)/administration/members/[userId]/page.tsx index 8201a748..036a83ce 100644 --- a/app/(main)/administration/members/[userId]/page.tsx +++ b/app/(main)/administration/members/[userId]/page.tsx @@ -42,42 +42,46 @@ export default async function TeamProfilePage({ [`/administration/members/${userId}`]: `${user.first_name || 'FirstName'} ${user.last_name || 'LastName'}`, }} /> -

Profile

+

+ {user.first_name} {user.last_name} +

{/* same styling as profile page */} -
-
-
- {user.first_name -
-

User Information

+
+
+
+
+ {user.first_name +
+

User Information

-
-
-
- -

{user.first_name}

-
-
- -

{user.last_name}

+
+
+
+ +

{user.first_name}

+
+
+ +

{user.last_name}

+
-
-
- -

{user.email}

-
+
+ +

{user.email}

+
-
- - +
+ + +
diff --git a/app/(main)/faq/page.tsx b/app/(main)/faq/page.tsx index cd95ea3c..f69d18c1 100644 --- a/app/(main)/faq/page.tsx +++ b/app/(main)/faq/page.tsx @@ -77,7 +77,7 @@ export default function FaqPage() { return (

FAQ

-
+

Roles & Permissions

diff --git a/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx b/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx index ae694f82..8d762f72 100644 --- a/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx +++ b/app/(main)/manage/[storeId]/add/components/AddStoreItemSearch.tsx @@ -250,31 +250,32 @@ export default function AddStoreItemSearch({

- -

Selected Items

- {fields.length > 0 ? ( -
- {fields.map((field, idx) => ( -
- handleRemove(idx)} - /> - -
- ))} -
- ) : ( -

No items selected.

- )} +
+

Selected Items

+ {fields.length > 0 ? ( +
+ {fields.map((field, idx) => ( +
+ handleRemove(idx)} + /> + +
+ ))} +
+ ) : ( +

No items selected.

+ )} +
); } diff --git a/app/(main)/profile/components/ProfileForm.module.css b/app/(main)/profile/components/ProfileForm.module.css index 13a84a71..dcb92dcb 100644 --- a/app/(main)/profile/components/ProfileForm.module.css +++ b/app/(main)/profile/components/ProfileForm.module.css @@ -1,18 +1,15 @@ .card { - border: none; - border-radius: 5px; - background: #fff; - margin-top: 8.25rem; + margin-top: 6.25rem; } .cardBody { - padding: 40px; - padding-top: 6.25rem; - margin-top: 50px; + padding: 6.25rem 1.5rem 1.5rem 1.5rem; } -.userInfoText { - margin-top: 1.25rem; +@media (min-width: 576px) { + .cardBody { + padding: 6.25rem 3rem 3rem 3rem; + } } .avatarCircle { @@ -36,12 +33,6 @@ margin-top: -12.5rem; } -.fieldGroup { - display: flex; - flex-direction: column; - margin-bottom: 16px; -} - .profileLabel { font-weight: 500; margin-bottom: 5px; diff --git a/app/(main)/profile/components/ProfileForm.tsx b/app/(main)/profile/components/ProfileForm.tsx index 7b986e57..597da449 100644 --- a/app/(main)/profile/components/ProfileForm.tsx +++ b/app/(main)/profile/components/ProfileForm.tsx @@ -145,7 +145,7 @@ export default function ProfileForm({ user }: { user: User }) { }; return ( -
+
{isEditing ? ( @@ -172,12 +172,12 @@ export default function ProfileForm({ user }: { user: User }) { />
)} -

User Information

+

User Information

- + {isEditing ? ( <>
- + {isEditing ? ( <>
-

Change Password

+

Change Password

Profile

- - - -
+
+
+ +
-
-
- +
+ +
); diff --git a/app/globals.css b/app/globals.css index d184caf1..3575b224 100644 --- a/app/globals.css +++ b/app/globals.css @@ -236,7 +236,7 @@ Table { } .content-body { - gap: 1.25rem; + gap: 2rem; display: flex; flex-direction: column; } From 057431598e72f664ac533c689ed1fa8a65f0c8d9 Mon Sep 17 00:00:00 2001 From: joy-y-cheng Date: Mon, 18 May 2026 00:23:39 -0700 Subject: [PATCH 3/5] Make administration styles more consistent --- .../components/DonationsExportForm.tsx | 116 +++++++++--------- app/(main)/administration/exports/page.tsx | 52 ++++---- .../[storeId]/components/AddAdminSearch.tsx | 66 ++++++---- .../store-admins/[storeId]/page.tsx | 61 ++++----- app/(main)/administration/stores/page.tsx | 20 +-- app/(main)/faq/FaqPage.module.css | 1 + app/(main)/faq/page.tsx | 36 +++--- app/globals.css | 4 + 8 files changed, 192 insertions(+), 164 deletions(-) diff --git a/app/(main)/administration/exports/components/DonationsExportForm.tsx b/app/(main)/administration/exports/components/DonationsExportForm.tsx index 88671cd3..6f8cf5ca 100644 --- a/app/(main)/administration/exports/components/DonationsExportForm.tsx +++ b/app/(main)/administration/exports/components/DonationsExportForm.tsx @@ -66,67 +66,69 @@ export default function Donations() { return ( -

Export Gift-in-Kind Records

- -
- -
- - -
-
- - {dateMode === 'range' && ( -
- - Start date - +

Export Gift-in-Kind Records

+ +
+ +
+ - - {errors.startDate?.message} - - - - - End date - - - {errors.endDate?.message} - - -
- )} +
+
-
- + {dateMode === 'range' && ( +
+ + Start date + + + {errors.startDate?.message} + + + + + End date + + + {errors.endDate?.message} + + +
+ )} + +
+ +
-
- + +
); diff --git a/app/(main)/administration/exports/page.tsx b/app/(main)/administration/exports/page.tsx index fe49f1c4..39f6c06b 100644 --- a/app/(main)/administration/exports/page.tsx +++ b/app/(main)/administration/exports/page.tsx @@ -26,30 +26,34 @@ export default async function ExportsPage() {

Exports

- -

Recent Gift-in-Kind Records

- - - - - - - - - - - {sortedDonations.map((item) => ( - - - - - - - ))} - -
ReceiverStoreItems DonatedDate Submitted
- {item.receiver_first_name} {item.receiver_last_name} - {item.store_name}{item.items_donated}{new Date(item.date_submitted).toLocaleString()}
+
+ +
+

Recent Gift-in-Kind Records

+ + + + + + + + + + + {sortedDonations.map((item) => ( + + + + + + + ))} + +
ReceiverStoreItems DonatedDate Submitted
+ {item.receiver_first_name} {item.receiver_last_name} + {item.store_name}{item.items_donated}{new Date(item.date_submitted).toLocaleString()}
+
+
); } diff --git a/app/(main)/administration/store-admins/[storeId]/components/AddAdminSearch.tsx b/app/(main)/administration/store-admins/[storeId]/components/AddAdminSearch.tsx index eff1df0b..3717eca9 100644 --- a/app/(main)/administration/store-admins/[storeId]/components/AddAdminSearch.tsx +++ b/app/(main)/administration/store-admins/[storeId]/components/AddAdminSearch.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'; import { createClient } from '@/app/lib/supabase/browser-client'; import { createStoreAdmin } from '@/app/actions/store'; import { User } from '@/app/types/user'; -import { Form, ListGroup } from 'react-bootstrap'; +import { Form, ListGroup, Card } from 'react-bootstrap'; const supabase = createClient(); @@ -50,32 +50,44 @@ export default function AddAdminSearch({ }, [search, existingAdminUserIds]); return ( -
- {/* searching */} -
- setSearch(e.target.value)} - /> -
+ + +
+

Add New Admins

+ {/* searching */} +
+
+ setSearch(e.target.value)} + /> +
- {/* search results */} - - {searchData.map((u) => ( - - createStoreAdmin({ user_id: u.user_id, store_id: storeId }) - } - > - {u.first_name} - - ))} - -
+ {/* search results */} + {searchData.length > 0 && ( + + {searchData.map((u) => ( + + createStoreAdmin({ + user_id: u.user_id, + store_id: storeId, + }) + } + > + {u.first_name} + + ))} + + )} +
+
+ + ); } diff --git a/app/(main)/administration/store-admins/[storeId]/page.tsx b/app/(main)/administration/store-admins/[storeId]/page.tsx index 3a01c2d7..26618d03 100644 --- a/app/(main)/administration/store-admins/[storeId]/page.tsx +++ b/app/(main)/administration/store-admins/[storeId]/page.tsx @@ -2,6 +2,8 @@ import { createClient } from '@/app/lib/supabase/server-client'; import AddAdminSearch from '@/app/(main)/administration/store-admins/[storeId]/components/AddAdminSearch'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; import AddAdminCard from '@/app/(main)/administration/store-admins/[storeId]/components/AddAdminCard'; +import Image from 'next/image'; +import pinIcon from '@/public/pin-icon.svg'; export default async function StoreAdminPage({ params, @@ -85,42 +87,41 @@ export default async function StoreAdminPage({ store_data?.name ?? 'Store', }} /> -
-

{store_data.name}

-

{store_data.street_address}

-
+

+ {store_data.name} + Pin icon +

- {/* searching store admins (AddAdminSearch) if eligible role */} - {canChangeAdmins && ( -
-

Add New Admins

+
+ {/* searching store admins (AddAdminSearch) if eligible role */} + {canChangeAdmins && ( -
- )} + )} - {/* viewing store admins */} -
-

Current Admins

-
- {admins?.length ? ( - admins.map((admin) => { - const user = admin.users; - return ( -
- -
- ); - }) - ) : ( -
No admins found.
- )} + {/* viewing store admins */} +
+

Current Admins

+
+ {admins?.length ? ( + admins.map((admin) => { + const user = admin.users; + return ( +
+ +
+ ); + }) + ) : ( +
No admins found.
+ )} +
diff --git a/app/(main)/administration/stores/page.tsx b/app/(main)/administration/stores/page.tsx index c2bfefac..f1caf0d5 100644 --- a/app/(main)/administration/stores/page.tsx +++ b/app/(main)/administration/stores/page.tsx @@ -3,7 +3,7 @@ import StoresList from '@/app/(main)/components/StoresList'; import AddStoreForm from '@/app/(main)/administration/stores/components/AddStoreForm'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; -export default async function HqPage() { +export default async function StoresPage() { const supabase = await createClient(); const { data: storesData, error: storesErr } = await supabase @@ -20,13 +20,17 @@ export default async function HqPage() {

Stores

- -

Edit Stores

- {stores.length > 0 ? ( - - ) : ( -

No stores found.

- )} +
+ +
+

Edit Stores

+ {stores.length > 0 ? ( + + ) : ( +

No stores found.

+ )} +
+
); } diff --git a/app/(main)/faq/FaqPage.module.css b/app/(main)/faq/FaqPage.module.css index dea6aa2f..4ece195a 100644 --- a/app/(main)/faq/FaqPage.module.css +++ b/app/(main)/faq/FaqPage.module.css @@ -6,6 +6,7 @@ .sectionDescription { color: #4f5d75; + margin-bottom: 0; } .card { diff --git a/app/(main)/faq/page.tsx b/app/(main)/faq/page.tsx index f69d18c1..ebac5937 100644 --- a/app/(main)/faq/page.tsx +++ b/app/(main)/faq/page.tsx @@ -78,37 +78,37 @@ export default function FaqPage() {

FAQ

-
+

Roles & Permissions

Roles determine what pages you can access and what actions you can take. Higher roles inherit all permissions from roles below them.

+
-
- {roleCards.map((card) => ( -
- -
- ))} -
-
+
+ {roleCards.map((card) => ( +
+ +
+ ))} +
-
+

Ticket Statuses

Once a ticket is submitted, tickets move through the following statuses as store admins review and fulfill them.

+
-
- {statusCards.map((card) => ( -
- -
- ))} -
-
+
+ {statusCards.map((card) => ( +
+ +
+ ))} +
); diff --git a/app/globals.css b/app/globals.css index 3575b224..68f53ae3 100644 --- a/app/globals.css +++ b/app/globals.css @@ -18,21 +18,25 @@ h1 { h2 { font-weight: 600; font-size: 1.5rem; + margin-bottom: 1.25rem; } h3 { font-weight: 600; font-size: 1.5rem; + margin-bottom: 1.25rem; } h4 { font-weight: 500; font-size: 1rem; + margin-bottom: 1rem; } p { font-weight: 400; font-size: 1rem; + margin-bottom: 1rem; } th { From 0a10f75e4247a411f6f326d8d8c59f3ea27ad6ca Mon Sep 17 00:00:00 2001 From: joy-y-cheng Date: Mon, 18 May 2026 01:10:23 -0700 Subject: [PATCH 4/5] Clean up gallery pages --- app/(main)/manage/[storeId]/page.tsx | 76 ++++++------- .../components/EditCategories.tsx | 0 app/(main)/manage/categories/page.tsx | 63 +++++++++++ app/(main)/manage/inventory/page.tsx | 100 +++++++----------- app/(main)/manage/page.tsx | 23 ++-- app/(main)/request/[storeId]/page.tsx | 65 ++++++------ app/(main)/request/page.tsx | 20 ++-- app/globals.css | 10 +- 8 files changed, 210 insertions(+), 147 deletions(-) rename app/(main)/manage/{inventory/add => categories}/components/EditCategories.tsx (100%) create mode 100644 app/(main)/manage/categories/page.tsx diff --git a/app/(main)/manage/[storeId]/page.tsx b/app/(main)/manage/[storeId]/page.tsx index ae586aa3..bba72b15 100644 --- a/app/(main)/manage/[storeId]/page.tsx +++ b/app/(main)/manage/[storeId]/page.tsx @@ -129,47 +129,49 @@ export default async function ManageStorePage({ }} />
-

+

Managing {store.name} Pin icon

- Add and/or donate + + Add Items + +
+
+ ({ + id: cat.category_id, + name: cat.name, + })) || [] + } + subcategories={ + subcategories?.map((sub) => ({ + id: sub.subcategory_id, + name: sub.name, + category_id: sub.category_id, + })) || [] + } + /> + + {items && items.length > 0 ? ( +
+ {items.map((item) => ( +
+ +
+ ))} +
+ ) : ( +

No items found.

+ )}
- - ({ - id: cat.category_id, - name: cat.name, - })) || [] - } - subcategories={ - subcategories?.map((sub) => ({ - id: sub.subcategory_id, - name: sub.name, - category_id: sub.category_id, - })) || [] - } - /> - -

Items

- {items && items.length > 0 ? ( -
- {items.map((item) => ( -
- -
- ))} -
- ) : ( -

No items found.

- )}
); } diff --git a/app/(main)/manage/inventory/add/components/EditCategories.tsx b/app/(main)/manage/categories/components/EditCategories.tsx similarity index 100% rename from app/(main)/manage/inventory/add/components/EditCategories.tsx rename to app/(main)/manage/categories/components/EditCategories.tsx diff --git a/app/(main)/manage/categories/page.tsx b/app/(main)/manage/categories/page.tsx new file mode 100644 index 00000000..e5d27efd --- /dev/null +++ b/app/(main)/manage/categories/page.tsx @@ -0,0 +1,63 @@ +import { createClient } from '@/app/lib/supabase/server-client'; +import EditCategories from '@/app/(main)/manage/categories/components/EditCategories'; +import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; + +export default async function InventoryPage() { + const supabase = await createClient(); + + const { data: claimsData } = await supabase.auth.getClaims(); + const role = claimsData?.claims?.user_role; + + const { data: categories, error } = await supabase + .from('categories') + .select(`category_id, name, subcategories(subcategory_id, name)`) + .order('name', { ascending: true }) + .order('name', { referencedTable: 'subcategories', ascending: true }) + .overrideTypes< + { + category_id: number; + name: string; + subcategories: { + name: string; + subcategory_id: number; + }[]; + }[], + { merge: false } + >(); + + if (error) { + console.error(error); + return
Failed to load categories.
; + } + + return ( +
+ +

Categories

+
+ {role === 'admin' && ( +
    + {categories?.map((cat) => ( +
  • + {cat.name} +
      + {cat.subcategories?.map((sub) => ( +
    • {sub.name}
    • + ))} +
    +
  • + ))} +
+ )} + + {(role === 'superadmin' || role === 'owner') && ( + + )} +
+
+ ); +} diff --git a/app/(main)/manage/inventory/page.tsx b/app/(main)/manage/inventory/page.tsx index 1a7da94f..7c702a78 100644 --- a/app/(main)/manage/inventory/page.tsx +++ b/app/(main)/manage/inventory/page.tsx @@ -1,7 +1,6 @@ import ItemCard from '@/app/(main)/components/ItemCard'; import { createClient } from '@/app/lib/supabase/server-client'; import Link from 'next/link'; -import EditCategories from '@/app/(main)/manage/inventory/add/components/EditCategories'; import ItemSearch from '@/app/(main)/components/ItemSearch'; import Breadcrumbs from '@/app/(main)/components/Breadcrumbs'; @@ -18,9 +17,6 @@ export default async function InventoryPage({ }) { const supabase = await createClient(); - const { data: claimsData } = await supabase.auth.getClaims(); - const role = claimsData?.claims?.user_role; - const { data: subcategories } = await supabase .from('subcategories') .select('subcategory_id, name, category_id') @@ -106,65 +102,45 @@ export default async function InventoryPage({ }} />
-

Inventory Library

- Add inventory item +

Inventory Library

+ + Add Item + +
+
+ ({ + id: cat.category_id, + name: cat.name, + })) || [] + } + subcategories={ + subcategories?.map((sub) => ({ + id: sub.subcategory_id, + name: sub.name, + category_id: sub.category_id, + })) || [] + } + /> + {items && items.length > 0 ? ( +
+ {items.map((item) => ( +
+ +
+ ))} +
+ ) : ( +

No items found.

+ )}
- - ({ - id: cat.category_id, - name: cat.name, - })) || [] - } - subcategories={ - subcategories?.map((sub) => ({ - id: sub.subcategory_id, - name: sub.name, - category_id: sub.category_id, - })) || [] - } - /> - -

Items

- {items && items.length > 0 ? ( -
- {items.map((item) => ( -
- -
- ))} -
- ) : ( -

No items found.

- )} - -

Categories

- - {role === 'admin' && ( -
    - {categories?.map((cat) => ( -
  • - {cat.name} -
      - {cat.subcategories?.map((sub) => ( -
    • {sub.name}
    • - ))} -
    -
  • - ))} -
- )} - - {(role === 'superadmin' || role === 'owner') && ( - - )}
); } diff --git a/app/(main)/manage/page.tsx b/app/(main)/manage/page.tsx index 34edf906..a947dca7 100644 --- a/app/(main)/manage/page.tsx +++ b/app/(main)/manage/page.tsx @@ -49,14 +49,21 @@ export default async function ManagePage() { return (

Manage Inventory

- -

Inventory Library

- - {stores.length > 0 ? ( - - ) : ( -

No stores found.

- )} +
+ + + Inventory Library + + + Item Categories + + + {stores.length > 0 ? ( + + ) : ( +

No stores found.

+ )} +
); } diff --git a/app/(main)/request/[storeId]/page.tsx b/app/(main)/request/[storeId]/page.tsx index 98db603d..b729f3d0 100644 --- a/app/(main)/request/[storeId]/page.tsx +++ b/app/(main)/request/[storeId]/page.tsx @@ -138,37 +138,40 @@ export default async function RequestStorePage({ Requesting from {store.name} Pin icon - ({ id: cat.category_id, name: cat.name })) || - [] - } - subcategories={ - subcategories?.map((sub) => ({ - id: sub.subcategory_id, - name: sub.name, - category_id: sub.category_id, - })) || [] - } - /> -

In-Stock Items

- {items && items.length > 0 ? ( -
- {items.map((item) => ( -
- -
- ))} -
- ) : ( -

No available items found.

- )} +
+ ({ + id: cat.category_id, + name: cat.name, + })) || [] + } + subcategories={ + subcategories?.map((sub) => ({ + id: sub.subcategory_id, + name: sub.name, + category_id: sub.category_id, + })) || [] + } + /> + {items && items.length > 0 ? ( +
+ {items.map((item) => ( +
+ +
+ ))} +
+ ) : ( +

No available items found.

+ )} +
Cart icon diff --git a/app/(main)/request/page.tsx b/app/(main)/request/page.tsx index d32a9941..b98e3ed2 100644 --- a/app/(main)/request/page.tsx +++ b/app/(main)/request/page.tsx @@ -18,14 +18,18 @@ export default async function RequestPage() { return (

Request Inventory

- -

All Stores

- - {stores.length > 0 ? ( - - ) : ( -

No stores found.

- )} +
+
+ + All Stores + +
+ {stores.length > 0 ? ( + + ) : ( +

No stores found.

+ )} +
); } diff --git a/app/globals.css b/app/globals.css index 68f53ae3..38d1b957 100644 --- a/app/globals.css +++ b/app/globals.css @@ -91,7 +91,8 @@ Table { align-items: center; justify-content: space-between; flex-wrap: wrap; - gap: 1rem; + gap: 2rem; + margin-bottom: 2rem; } /* ── white card container ── */ @@ -166,6 +167,7 @@ Table { } .btn-submit { + text-decoration: none; display: inline-flex; padding: 8px 40px; justify-content: center; @@ -233,6 +235,12 @@ Table { margin-bottom: 0; } +.link-btn-row { + gap: 2rem; + display: flex; + flex-direction: row; +} + .form-body { display: flex; flex-direction: column; From a34d798301e7290a4e6f9ec9eb0dfa3366ccaa21 Mon Sep 17 00:00:00 2001 From: joy-y-cheng Date: Mon, 18 May 2026 02:36:58 -0700 Subject: [PATCH 5/5] Update styling for inventory and store forms --- .../components/EditStoreForm.module.css | 9 +- .../components/RemoveStoreButton.tsx | 2 +- .../administration/stores/[storeId]/page.tsx | 8 +- .../stores/components/AddStoreForm.tsx | 2 +- app/(main)/components/PhotoUpload.tsx | 6 +- app/(main)/incoming-tickets/page.tsx | 2 +- .../components/AddInventoryItemForm.tsx | 43 +--- .../components/DeleteInventoryItemButton.tsx | 4 +- .../EditInventoryItemForm.module.css | 19 ++ .../components/EditInventoryItemForm.tsx | 206 +++++++++--------- .../inventory/[inventoryItemId]/page.tsx | 16 +- app/(main)/manage/inventory/add/page.tsx | 30 ++- app/(main)/outgoing-tickets/page.tsx | 2 +- 13 files changed, 178 insertions(+), 171 deletions(-) create mode 100644 app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.module.css diff --git a/app/(main)/administration/stores/[storeId]/components/EditStoreForm.module.css b/app/(main)/administration/stores/[storeId]/components/EditStoreForm.module.css index 58a73ae3..29ecb948 100644 --- a/app/(main)/administration/stores/[storeId]/components/EditStoreForm.module.css +++ b/app/(main)/administration/stores/[storeId]/components/EditStoreForm.module.css @@ -2,17 +2,18 @@ display: flex; align-items: flex-start; gap: 3rem; - margin-bottom: 40px; flex-wrap: wrap; } .photoColumn { - width: 200px; - height: 210px; + width: 16rem; + height: 16rem; flex-shrink: 0; } .fieldsColumn { + display: flex; + flex-direction: column; + gap: 1.25rem; flex: 1; - min-width: 0; } diff --git a/app/(main)/administration/stores/[storeId]/components/RemoveStoreButton.tsx b/app/(main)/administration/stores/[storeId]/components/RemoveStoreButton.tsx index 4d7223f4..a92d0b7c 100644 --- a/app/(main)/administration/stores/[storeId]/components/RemoveStoreButton.tsx +++ b/app/(main)/administration/stores/[storeId]/components/RemoveStoreButton.tsx @@ -27,7 +27,7 @@ export default function RemoveStoreButton({ storeId }: RemoveStoreButtonProp) { }; return ( - ); diff --git a/app/(main)/administration/stores/[storeId]/page.tsx b/app/(main)/administration/stores/[storeId]/page.tsx index 16b7a0cb..6b4d9a32 100644 --- a/app/(main)/administration/stores/[storeId]/page.tsx +++ b/app/(main)/administration/stores/[storeId]/page.tsx @@ -38,8 +38,12 @@ export default async function StoreDetailsPage({ }} />

{store.name}

- - +
+ +
+ +
+
); } diff --git a/app/(main)/administration/stores/components/AddStoreForm.tsx b/app/(main)/administration/stores/components/AddStoreForm.tsx index 23e76a2d..1b424359 100644 --- a/app/(main)/administration/stores/components/AddStoreForm.tsx +++ b/app/(main)/administration/stores/components/AddStoreForm.tsx @@ -97,7 +97,7 @@ export default function AddStoreForm() {
-
+
void }, PhotoUploadProps>( Profile photo ) : ( diff --git a/app/(main)/incoming-tickets/page.tsx b/app/(main)/incoming-tickets/page.tsx index f16ba03f..aef1c8d9 100644 --- a/app/(main)/incoming-tickets/page.tsx +++ b/app/(main)/incoming-tickets/page.tsx @@ -45,7 +45,7 @@ export default async function IncomingTicketsPage() { } return (
-

Incoming Tickets

+

Store Tickets

{stores.length > 0 ? ( ) : ( diff --git a/app/(main)/manage/components/AddInventoryItemForm.tsx b/app/(main)/manage/components/AddInventoryItemForm.tsx index 56b982e2..0f298a6e 100644 --- a/app/(main)/manage/components/AddInventoryItemForm.tsx +++ b/app/(main)/manage/components/AddInventoryItemForm.tsx @@ -3,11 +3,8 @@ import { createClient } from '@/app/lib/supabase/browser-client'; import { Subcategory, Category } from '@/app/types/inventory'; import { useFormContext } from 'react-hook-form'; import { useEffect, useState, useRef } from 'react'; -import Image from 'next/image'; import PhotoUpload from '@/app/(main)/components/PhotoUpload'; -import defaultItemPhoto from '@/public/image-placeholder.svg'; import { Form } from 'react-bootstrap'; -import donationStyles from '@/app/(main)/components/DonationForm.module.css'; import styles from '@/app/(main)/manage/components/AddInventoryItemForm.module.css'; export type Inputs = { @@ -111,12 +108,10 @@ export default function AddInventoryItemForm({ }, [selectedCategory]); return ( -
+
{/* Item Title */} - - Item Title - + Item Title {/* Image */} - Image + Image {/* placeholder for drag and drop */} -
- Item photo + - {selectedFile && ( - - )} -
- -
{/* Description */} - - Description - + Description - Category + Category {/* subcategory */} - - Subcategory - + Subcategory - Remove item + ); } diff --git a/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.module.css b/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.module.css new file mode 100644 index 00000000..29ecb948 --- /dev/null +++ b/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.module.css @@ -0,0 +1,19 @@ +.layout { + display: flex; + align-items: flex-start; + gap: 3rem; + flex-wrap: wrap; +} + +.photoColumn { + width: 16rem; + height: 16rem; + flex-shrink: 0; +} + +.fieldsColumn { + display: flex; + flex-direction: column; + gap: 1.25rem; + flex: 1; +} diff --git a/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.tsx b/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.tsx index ca833941..b773304f 100644 --- a/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.tsx +++ b/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.tsx @@ -7,11 +7,10 @@ import type { InventoryItem, Subcategory, } from '@/app/types/inventory'; -import Image from 'next/image'; import PhotoUpload from '@/app/(main)/components/PhotoUpload'; -import defaultItemPhoto from '@/public/image-placeholder.svg'; import { useEffect, useRef, useState } from 'react'; import { useForm, useWatch, type SubmitHandler } from 'react-hook-form'; +import styles from '@/app/(main)/manage/inventory/[inventoryItemId]/components/EditInventoryItemForm.module.css'; type FormValues = { name: string; @@ -215,123 +214,112 @@ export default function EditInventoryItemForm({ }, }); - const displayImage = isPendingDelete - ? defaultItemPhoto.src - : previewUrl || photoUrl || defaultItemPhoto.src; - const hasDirtyTextOrImage = isDirty || !!selectedFile || isPendingDelete; return (
-
- Item photo - - {!isPendingDelete && displayImage !== defaultItemPhoto.src && ( - - )} - -
- -
- -
- - - {errors.name &&

{errors.name.message}

} -
- -
- - - {errors.description && ( -

{errors.description.message}

- )} -
- -
- - -
+
+
+ +
+
+
+ + + {errors.name &&

{errors.name.message}

} +
+ +
+ + + {errors.description && ( +

{errors.description.message}

+ )} +
+ +
+ + +
+ + {!!selectedCategory && ( +
+ + + {errors.selectedSubcategory && ( +

{errors.selectedSubcategory.message}

+ )} +
+ )} - {!!selectedCategory && ( -
- - - {errors.selectedSubcategory && ( -

{errors.selectedSubcategory.message}

+ {isSubmitting ? 'Saving...' : 'Save'} + + +
)}
- )} - - {hasDirtyTextOrImage && ( -
- - -
- )} +
diff --git a/app/(main)/manage/inventory/[inventoryItemId]/page.tsx b/app/(main)/manage/inventory/[inventoryItemId]/page.tsx index 52e8a088..e84dd593 100644 --- a/app/(main)/manage/inventory/[inventoryItemId]/page.tsx +++ b/app/(main)/manage/inventory/[inventoryItemId]/page.tsx @@ -102,12 +102,16 @@ export default async function InventoryItemPage({ }} />

{item.name}

- - +
+ +
+ +
+
); } diff --git a/app/(main)/manage/inventory/add/page.tsx b/app/(main)/manage/inventory/add/page.tsx index cebcb799..67c7ad37 100644 --- a/app/(main)/manage/inventory/add/page.tsx +++ b/app/(main)/manage/inventory/add/page.tsx @@ -82,17 +82,27 @@ export default function AddInventoryItemPage() { add: 'Add Inventory Item', }} /> -

Add Inventory Item

- -
- - - -
+
+
+ +
+ +
+ +
+ +
+
+
); } diff --git a/app/(main)/outgoing-tickets/page.tsx b/app/(main)/outgoing-tickets/page.tsx index e5db4cd8..ef3c499c 100644 --- a/app/(main)/outgoing-tickets/page.tsx +++ b/app/(main)/outgoing-tickets/page.tsx @@ -27,7 +27,7 @@ export default async function OutgoingTicketsPage() { return (
-

Outgoing Tickets

+

My Tickets

);