Skip to content

Commit

Permalink
Set item collection, preview store as member
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepTester committed Jan 18, 2024
1 parent e2b510f commit 89b92f5
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 96 deletions.
150 changes: 82 additions & 68 deletions src/components/admin/store/ItemDetailsForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import EventDetailsFormItem from '@/components/admin/event/EventDetailsFormItem'
import { Button } from '@/components/common';
import { config, showToast } from '@/lib';
import { StoreAPI } from '@/lib/api';
import { AdminEventManager } from '@/lib/managers';
import { CookieService } from '@/lib/services';
import { MerchItem } from '@/lib/types/apiRequests';
import { PublicMerchItem } from '@/lib/types/apiResponses';
import { PublicMerchCollection, PublicMerchItem } from '@/lib/types/apiResponses';
import { CookieType } from '@/lib/types/enums';
import { reportError } from '@/lib/utils';
import { useRouter } from 'next/navigation';
Expand All @@ -18,9 +17,10 @@ type FormValues = Omit<MerchItem, 'uuid' | 'merchPhotos' | 'options'>;
interface IProps {
mode: 'create' | 'edit';
defaultData?: Partial<PublicMerchItem>;
collections: PublicMerchCollection[];
}

const ItemDetailsForm = ({ mode, defaultData = {} }: IProps) => {
const ItemDetailsForm = ({ mode, defaultData = {}, collections }: IProps) => {
const router = useRouter();
const initialValues: FormValues = {
itemName: defaultData.itemName ?? '',
Expand Down Expand Up @@ -59,10 +59,10 @@ const ItemDetailsForm = ({ mode, defaultData = {} }: IProps) => {
showToast('Item created successfully!', '', [
{
text: 'View public item page',
onClick: () => router.push(`${config.admin.store.items}/${uuid}`),
onClick: () => router.push(`${config.store.itemRoute}/${uuid}`),
},
]);
router.push(`${config.admin.store.items}/${uuid}/edit`);
router.push(`${config.store.itemRoute}/${uuid}/edit`);
} catch (error) {
reportError('Could not create item', error);
} finally {
Expand All @@ -81,98 +81,112 @@ const ItemDetailsForm = ({ mode, defaultData = {} }: IProps) => {
showToast('Item details saved!', '', [
{
text: 'View public item page',
onClick: () => router.push(`${config.admin.store.items}/${uuid}`),
onClick: () => router.push(`${config.store.itemRoute}/${uuid}`),
},
]);
router.push(`${config.admin.store.items}/${uuid}/edit`);
} catch (error) {
reportError('Could not save changes', error);
} finally {
setLoading(false);
}
};

const deleteItem = () => {
const deleteItem = async () => {
setLoading(true);
const AUTH_TOKEN = CookieService.getClientCookie(CookieType.ACCESS_TOKEN);
AdminEventManager.deleteEvent({
event: defaultData.uuid ?? '',
token: AUTH_TOKEN,
onSuccessCallback: () => {
setLoading(false);
router.push(config.admin.events.homeRoute);
},
});
try {
await StoreAPI.deleteItem(AUTH_TOKEN, defaultData.uuid ?? '');
showToast('Item details saved!', '', [
{
text: 'View public item page',
onClick: () => router.push(config.store.homeRoute),
},
]);
router.push(config.store.homeRoute);
} catch (error) {
reportError('Could not delete item', error);
} finally {
setLoading(false);
}
};

return (
<form onSubmit={handleSubmit(mode === 'edit' ? editItem : createItem)}>
<h1>{mode === 'edit' ? 'Modify' : 'Create'} store item</h1>
<label htmlFor="name">Item name</label>
<EventDetailsFormItem error={errors.itemName?.message}>
<input
type="text"
id="name"
placeholder="ACM Cafe"
{...register('itemName', {
required: 'Required',
})}
/>
</EventDetailsFormItem>

<label htmlFor="description">Description</label>
<EventDetailsFormItem error={errors.description?.message}>
<textarea
id="description"
{...register('description', {
required: 'Required',
})}
/>
</EventDetailsFormItem>

<label htmlFor="monthlyLimit">Monthly limit</label>
<EventDetailsFormItem error={errors.monthlyLimit?.message}>
<input
type="number"
id="monthlyLimit"
{...register('monthlyLimit', {
required: 'Required',
})}
/>
</EventDetailsFormItem>
<div className={style.form}>
<label htmlFor="name">Item name</label>
<EventDetailsFormItem error={errors.itemName?.message}>
<input
type="text"
id="name"
placeholder="ACM Cafe"
{...register('itemName', {
required: 'Required',
})}
/>
</EventDetailsFormItem>

<label htmlFor="lifetimeLimit">Lifetime limit</label>
<EventDetailsFormItem error={errors.lifetimeLimit?.message}>
<input
type="number"
id="lifetimeLimit"
{...register('lifetimeLimit', {
required: 'Required',
})}
/>
</EventDetailsFormItem>
<label htmlFor="description">Description</label>
<EventDetailsFormItem error={errors.description?.message}>
<textarea
id="description"
{...register('description', {
required: 'Required',
})}
/>
</EventDetailsFormItem>

<label htmlFor="collection">Collection</label>
<EventDetailsFormItem error={errors.collection?.message}>
<select
id="collection"
placeholder="General"
{...register('collection', {
required: 'Required',
})}
>
{collections.map(collection => (
<option key={collection.uuid} value={collection.uuid}>
{collection.title}
</option>
))}
</select>
</EventDetailsFormItem>

<label htmlFor="monthlyLimit">Monthly limit</label>
<EventDetailsFormItem error={errors.monthlyLimit?.message}>
<input
type="number"
id="monthlyLimit"
{...register('monthlyLimit', {
required: 'Required',
})}
/>
</EventDetailsFormItem>

<EventDetailsFormItem error={errors.hidden?.message}>
<label>
<label htmlFor="lifetimeLimit">Lifetime limit</label>
<EventDetailsFormItem error={errors.lifetimeLimit?.message}>
<input
type="checkbox"
{...register('hidden', {
type="number"
id="lifetimeLimit"
{...register('lifetimeLimit', {
required: 'Required',
})}
/>
</EventDetailsFormItem>
</div>

<EventDetailsFormItem error={errors.hidden?.message}>
<label>
<input type="checkbox" {...register('hidden')} />
&nbsp;Hidden?
</label>
</EventDetailsFormItem>

<EventDetailsFormItem error={errors.hasVariantsEnabled?.message}>
<label>
<input
type="checkbox"
id="hasVariantsEnabled"
{...register('hasVariantsEnabled', {
required: 'Required',
})}
/>
<input type="checkbox" id="hasVariantsEnabled" {...register('hasVariantsEnabled')} />
&nbsp;Has variants?
</label>
</EventDetailsFormItem>
Expand Down
7 changes: 7 additions & 0 deletions src/components/admin/store/ItemDetailsForm/style.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
@use 'src/styles/vars.scss' as vars;

.form {
column-gap: 8px;
display: grid;
grid-template-columns: 1fr 3fr;
row-gap: 1rem;
}

.submitButtons {
display: flex;
gap: 1rem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type Styles = {
form: string;
submitButtons: string;
};

Expand Down
39 changes: 33 additions & 6 deletions src/pages/store/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,33 @@ import { useState } from 'react';

type View = 'collections' | 'all-items';

function getPath(view: View, previewPublic: boolean): string {
const params = new URLSearchParams();
if (view === 'all-items') {
params.set('view', 'all');
}
if (previewPublic) {
params.set('preview', 'public');
}
return params.size > 0 ? `${config.store.homeRoute}?${params}` : config.store.homeRoute;
}

interface HomePageProps {
user: PrivateProfile;
view: View;
collections: PublicMerchCollection[];
previewPublic: boolean;
}
const StoreHomePage = ({ user: { credits }, view, collections }: HomePageProps) => {
const StoreHomePage = ({
user: { credits, accessType },
view,
collections,
previewPublic,
}: HomePageProps) => {
const [helpOpen, setHelpOpen] = useState(false);

const canManageStore = PermissionService.canEditMerchItems.includes(accessType) && !previewPublic;

return (
<>
<div className={styles.container}>
Expand All @@ -31,11 +50,14 @@ const StoreHomePage = ({ user: { credits }, view, collections }: HomePageProps)
<div className={styles.container}>
<div className={styles.header}>
<h2>{view === 'collections' ? 'Browse our collections' : 'Browse all items'}</h2>
{canManageStore && (
<Link className={styles.viewToggle} href={getPath(view, true)}>
View store as member
</Link>
)}
<Link
className={styles.viewToggle}
href={
view === 'collections' ? `${config.store.homeRoute}?view=all` : config.store.homeRoute
}
href={getPath(view === 'collections' ? 'all-items' : 'collections', previewPublic)}
scroll={false}
>
{view === 'collections' ? 'See all items' : 'See collections'}
Expand All @@ -49,7 +71,9 @@ const StoreHomePage = ({ user: { credits }, view, collections }: HomePageProps)
title={collection.title}
description={collection.description}
href={`${config.store.collectionRoute}${collection.uuid}`}
editUrl={`${config.store.collectionRoute}${collection.uuid}/edit`}
editUrl={
canManageStore ? `${config.store.collectionRoute}${collection.uuid}/edit` : null
}
key={collection.uuid}
/>
))}
Expand All @@ -60,7 +84,9 @@ const StoreHomePage = ({ user: { credits }, view, collections }: HomePageProps)
title={collection.title}
description={collection.description}
items={collection.items}
editUrl={`${config.collectionRoute}${collection.uuid}/edit`}
editUrl={
canManageStore ? `${config.store.collectionRoute}${collection.uuid}/edit` : null
}
key={collection.uuid}
/>
))
Expand All @@ -81,6 +107,7 @@ const getServerSidePropsFunc: GetServerSideProps = async ({ req, res, query }) =
props: {
view: query.view === 'all' ? 'all-items' : 'collections',
collections,
previewPublic: query.preview === 'public',
},
};
};
Expand Down
18 changes: 9 additions & 9 deletions src/pages/store/item/[uuid]/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@ import { StoreAPI } from '@/lib/api';
import config from '@/lib/config';
import withAccessType from '@/lib/hoc/withAccessType';
import { CookieService, PermissionService } from '@/lib/services';
import { PrivateProfile, PublicMerchItem } from '@/lib/types/apiResponses';
import { PrivateProfile, PublicMerchCollection, PublicMerchItem } from '@/lib/types/apiResponses';
import { CookieType } from '@/lib/types/enums';
import styles from '@/styles/pages/StoreItemEditPage.module.scss';
import { GetServerSideProps } from 'next';

interface ItemEditPageProps {
user: PrivateProfile;
item: PublicMerchItem;
collections: PublicMerchCollection[];
}
const ItemEditPage = ({ user: { credits }, item }: ItemEditPageProps) => {
const ItemEditPage = ({ user: { credits }, item, collections }: ItemEditPageProps) => {
return (
<div className={styles.container}>
<Navbar balance={credits} showBack />
<ItemDetailsForm mode="edit" defaultData={item} />
<ItemDetailsForm mode="edit" defaultData={item} collections={collections} />
</div>
);
};
Expand All @@ -29,12 +30,11 @@ const getServerSidePropsFunc: GetServerSideProps = async ({ params, req, res })
const token = CookieService.getServerCookie(CookieType.ACCESS_TOKEN, { req, res });

try {
const item = await StoreAPI.getItem(uuid, token);
return {
props: {
item,
},
};
const [item, collections] = await Promise.all([
StoreAPI.getItem(uuid, token),
StoreAPI.getAllCollections(token),
]);
return { props: { item, collections } };
} catch (err: any) {
return { redirect: { destination: config.store.homeRoute, permanent: false } };
}
Expand Down
Loading

0 comments on commit 89b92f5

Please sign in to comment.