From 4b64778b590761c69749188f7398b1e5b0f1a447 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Sun, 15 Jun 2025 16:33:50 +0800 Subject: [PATCH] refactor: rename product to party-event across frontend modules and types --- .../src/app/api/party-event/list/route.ts | 4 +- 03_source/frontend/src/actions/party-event.ts | 44 ++++++++------- 03_source/frontend/src/lib/axios.ts | 8 +++ .../party-event-details-carousel.tsx | 4 +- .../party-event-details-summary.tsx | 4 +- .../sections/party-event/party-event-item.tsx | 4 +- .../sections/party-event/party-event-list.tsx | 6 +- .../party-event/party-event-new-edit-form.tsx | 6 +- .../party-event/party-event-search.tsx | 8 +-- .../party-event/party-event-table-toolbar.tsx | 2 +- .../view/party-event-details-view.tsx | 4 +- .../view/party-event-edit-view.tsx | 4 +- .../view/party-event-list-view.tsx | 56 ++++++++++--------- .../view/party-event-shop-details-view.tsx | 4 +- .../view/party-event-shop-view.tsx | 10 ++-- 03_source/frontend/src/types/party-event.ts | 2 +- 16 files changed, 93 insertions(+), 77 deletions(-) diff --git a/03_source/cms_backend/src/app/api/party-event/list/route.ts b/03_source/cms_backend/src/app/api/party-event/list/route.ts index c5b7802..ecf8667 100644 --- a/03_source/cms_backend/src/app/api/party-event/list/route.ts +++ b/03_source/cms_backend/src/app/api/party-event/list/route.ts @@ -25,11 +25,11 @@ export async function GET(req: NextRequest) { const debug = { 'req.headers': flattenNextjsRequest(req) }; try { - const events = await listEvents(); + const partyEvents = await listEvents(); createAppLog(L_INFO, 'party-event list ok', {}); - return response({ events }, STATUS.OK); + return response({ partyEvents }, STATUS.OK); } catch (error) { createAppLog(L_ERROR, 'party-event list error', debug); diff --git a/03_source/frontend/src/actions/party-event.ts b/03_source/frontend/src/actions/party-event.ts index 06fdd46..2556316 100644 --- a/03_source/frontend/src/actions/party-event.ts +++ b/03_source/frontend/src/actions/party-event.ts @@ -2,7 +2,7 @@ // import { useMemo } from 'react'; import axiosInstance, { endpoints, fetcher } from 'src/lib/axios'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import type { SWRConfiguration } from 'swr'; import useSWR, { mutate } from 'swr'; @@ -16,24 +16,28 @@ const swrOptions: SWRConfiguration = { // ---------------------------------------------------------------------- -type ProductsData = { - products: IProductItem[]; +type PartyEventsData = { + partyEvents: IPartyEventItem[]; }; -export function useGetProducts() { - const url = endpoints.product.list; +export function useGetPartyEvents() { + const url = endpoints.partyEvent.list; - const { data, isLoading, error, isValidating } = useSWR(url, fetcher, swrOptions); + const { data, isLoading, error, isValidating } = useSWR( + url, + fetcher, + swrOptions + ); const memoizedValue = useMemo( () => ({ - products: data?.products || [], - productsLoading: isLoading, - productsError: error, - productsValidating: isValidating, - productsEmpty: !isLoading && !isValidating && !data?.products.length, + partyEvents: data?.partyEvents || [], + partyEventsLoading: isLoading, + partyEventsError: error, + partyEventsValidating: isValidating, + partyEventsEmpty: !isLoading && !isValidating && !data?.partyEvents.length, }), - [data?.products, error, isLoading, isValidating] + [data?.partyEvents, error, isLoading, isValidating] ); return memoizedValue; @@ -42,7 +46,7 @@ export function useGetProducts() { // ---------------------------------------------------------------------- type ProductData = { - product: IProductItem; + product: IPartyEventItem; }; export function useGetPartyEvent(productId: string) { @@ -67,7 +71,7 @@ export function useGetPartyEvent(productId: string) { // ---------------------------------------------------------------------- type SearchResultsData = { - results: IProductItem[]; + results: IPartyEventItem[]; }; export function useSearchProducts(query: string) { @@ -94,7 +98,7 @@ export function useSearchProducts(query: string) { // ---------------------------------------------------------------------- -export async function createProduct(productData: IProductItem) { +export async function createProduct(productData: IPartyEventItem) { /** * Work on server */ @@ -109,7 +113,7 @@ export async function createProduct(productData: IProductItem) { mutate( endpoints.product.list, (currentData: any) => { - const currentProducts: IProductItem[] = currentData?.products; + const currentProducts: IPartyEventItem[] = currentData?.products; const products = [...currentProducts, { ...productData, id }]; @@ -121,7 +125,7 @@ export async function createProduct(productData: IProductItem) { // ---------------------------------------------------------------------- -export async function updateProduct(productData: Partial) { +export async function updateProduct(productData: Partial) { /** * Work on server */ @@ -135,7 +139,7 @@ export async function updateProduct(productData: Partial) { mutate( endpoints.product.list, (currentData: any) => { - const currentProducts: IProductItem[] = currentData?.products; + const currentProducts: IPartyEventItem[] = currentData?.products; const products = currentProducts.map((product) => product.id === productData.id ? { ...product, ...productData } : product @@ -149,7 +153,7 @@ export async function updateProduct(productData: Partial) { // ---------------------------------------------------------------------- -export async function deleteProduct(productId: string) { +export async function deletePartyEvent(productId: string) { /** * Work on server */ @@ -164,7 +168,7 @@ export async function deleteProduct(productId: string) { endpoints.product.list, (currentData: any) => { console.log({ currentData }); - const currentProducts: IProductItem[] = currentData?.products; + const currentProducts: IPartyEventItem[] = currentData?.products; const products = currentProducts.filter((product) => product.id !== productId); diff --git a/03_source/frontend/src/lib/axios.ts b/03_source/frontend/src/lib/axios.ts index 4332393..64ba133 100644 --- a/03_source/frontend/src/lib/axios.ts +++ b/03_source/frontend/src/lib/axios.ts @@ -84,4 +84,12 @@ export const endpoints = { changeStatus: (invoiceId: string) => `/api/invoice/changeStatus?invoiceId=${invoiceId}`, search: '/api/invoice/search', }, + partyEvent: { + list: '/api/party-event/list', + details: '/api/party-event/details', + search: '/api/party-event/search', + create: '/api/party-event/create', + update: '/api/party-event/update', + delete: '/api/party-event/delete', + }, }; diff --git a/03_source/frontend/src/sections/party-event/party-event-details-carousel.tsx b/03_source/frontend/src/sections/party-event/party-event-details-carousel.tsx index ae372af..478f94a 100644 --- a/03_source/frontend/src/sections/party-event/party-event-details-carousel.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-details-carousel.tsx @@ -9,12 +9,12 @@ import { } from 'src/components/carousel'; import { Image } from 'src/components/image'; import { Lightbox, useLightBox } from 'src/components/lightbox'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; // ---------------------------------------------------------------------- type Props = { - images?: IProductItem['images']; + images?: IPartyEventItem['images']; }; export function ProductDetailsCarousel({ images }: Props) { diff --git a/03_source/frontend/src/sections/party-event/party-event-details-summary.tsx b/03_source/frontend/src/sections/party-event/party-event-details-summary.tsx index 61dbec2..38b859b 100644 --- a/03_source/frontend/src/sections/party-event/party-event-details-summary.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-details-summary.tsx @@ -17,13 +17,13 @@ import { NumberInput } from 'src/components/number-input'; import { useRouter } from 'src/routes/hooks'; import { paths } from 'src/routes/paths'; import type { CheckoutContextValue } from 'src/types/checkout'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { fCurrency, fShortenNumber } from 'src/utils/format-number'; // ---------------------------------------------------------------------- type Props = { - product: IProductItem; + product: IPartyEventItem; disableActions?: boolean; items?: CheckoutContextValue['state']['items']; onAddToCart?: CheckoutContextValue['onAddToCart']; diff --git a/03_source/frontend/src/sections/party-event/party-event-item.tsx b/03_source/frontend/src/sections/party-event/party-event-item.tsx index 62ef8f9..c2af365 100644 --- a/03_source/frontend/src/sections/party-event/party-event-item.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-item.tsx @@ -9,14 +9,14 @@ import { Iconify } from 'src/components/iconify'; import { Image } from 'src/components/image'; import { Label } from 'src/components/label'; import { RouterLink } from 'src/routes/components'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { fCurrency } from 'src/utils/format-number'; import { useCheckoutContext } from '../checkout/context'; // ---------------------------------------------------------------------- type Props = { - product: IProductItem; + product: IPartyEventItem; detailsHref: string; }; diff --git a/03_source/frontend/src/sections/party-event/party-event-list.tsx b/03_source/frontend/src/sections/party-event/party-event-list.tsx index c56793a..408d210 100644 --- a/03_source/frontend/src/sections/party-event/party-event-list.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-list.tsx @@ -2,7 +2,7 @@ import type { BoxProps } from '@mui/material/Box'; import Box from '@mui/material/Box'; import Pagination, { paginationClasses } from '@mui/material/Pagination'; import { paths } from 'src/routes/paths'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { ProductItem } from './party-event-item'; import { ProductItemSkeleton } from './party-event-skeleton'; @@ -10,10 +10,10 @@ import { ProductItemSkeleton } from './party-event-skeleton'; type Props = BoxProps & { loading?: boolean; - products: IProductItem[]; + products: IPartyEventItem[]; }; -export function ProductList({ products, loading, sx, ...other }: Props) { +export function PartyEventList({ products, loading, sx, ...other }: Props) { const renderLoading = () => ; const renderList = () => diff --git a/03_source/frontend/src/sections/party-event/party-event-new-edit-form.tsx b/03_source/frontend/src/sections/party-event/party-event-new-edit-form.tsx index 05aa056..0429031 100644 --- a/03_source/frontend/src/sections/party-event/party-event-new-edit-form.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-new-edit-form.tsx @@ -27,7 +27,7 @@ import { Iconify } from 'src/components/iconify'; import { toast } from 'src/components/snackbar'; import { useRouter } from 'src/routes/hooks'; import { paths } from 'src/routes/paths'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { fileToBase64 } from 'src/utils/file-to-base64'; import { z as zod } from 'zod'; @@ -128,7 +128,7 @@ export const NewProductSchema = zod.object({ // ---------------------------------------------------------------------- type Props = { - currentProduct?: IProductItem; + currentProduct?: IPartyEventItem; }; export function ProductNewEditForm({ currentProduct }: Props) { @@ -202,7 +202,7 @@ export function ProductNewEditForm({ currentProduct }: Props) { } } - const sanitizedValues: IProductItem = values as unknown as IProductItem; + const sanitizedValues: IPartyEventItem = values as unknown as IPartyEventItem; if (currentProduct) { // perform save diff --git a/03_source/frontend/src/sections/party-event/party-event-search.tsx b/03_source/frontend/src/sections/party-event/party-event-search.tsx index e835a75..7974b55 100644 --- a/03_source/frontend/src/sections/party-event/party-event-search.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-search.tsx @@ -15,7 +15,7 @@ import { Iconify } from 'src/components/iconify'; import { SearchNotFound } from 'src/components/search-not-found'; import { RouterLink } from 'src/routes/components'; import { useRouter } from 'src/routes/hooks'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; // ---------------------------------------------------------------------- @@ -28,13 +28,13 @@ export function ProductSearch({ redirectPath, sx }: Props) { const router = useRouter(); const [searchQuery, setSearchQuery] = useState(''); - const [selectedItem, setSelectedItem] = useState(null); + const [selectedItem, setSelectedItem] = useState(null); const debouncedQuery = useDebounce(searchQuery); const { searchResults: options, searchLoading: loading } = useSearchProducts(debouncedQuery); const handleChange = useCallback( - (item: IProductItem | null) => { + (item: IPartyEventItem | null) => { setSelectedItem(item); if (item) { router.push(redirectPath(item.id)); @@ -45,7 +45,7 @@ export function ProductSearch({ redirectPath, sx }: Props) { const filterOptions = createFilterOptions({ matchFrom: 'any', - stringify: (option: IProductItem) => `${option.name} ${option.sku}`, + stringify: (option: IPartyEventItem) => `${option.name} ${option.sku}`, }); const paperStyles: SxProps = { diff --git a/03_source/frontend/src/sections/party-event/party-event-table-toolbar.tsx b/03_source/frontend/src/sections/party-event/party-event-table-toolbar.tsx index b04047f..9097003 100644 --- a/03_source/frontend/src/sections/party-event/party-event-table-toolbar.tsx +++ b/03_source/frontend/src/sections/party-event/party-event-table-toolbar.tsx @@ -25,7 +25,7 @@ type Props = { }; }; -export function ProductTableToolbar({ filters, options }: Props) { +export function PartyEventTableToolbar({ filters, options }: Props) { const menuActions = usePopover(); const { state: currentFilters, setState: updateFilters } = filters; diff --git a/03_source/frontend/src/sections/party-event/view/party-event-details-view.tsx b/03_source/frontend/src/sections/party-event/view/party-event-details-view.tsx index 91f0c79..42bef08 100644 --- a/03_source/frontend/src/sections/party-event/view/party-event-details-view.tsx +++ b/03_source/frontend/src/sections/party-event/view/party-event-details-view.tsx @@ -17,7 +17,7 @@ import { Iconify } from 'src/components/iconify'; import { DashboardContent } from 'src/layouts/dashboard'; import { RouterLink } from 'src/routes/components'; import { paths } from 'src/routes/paths'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { ProductDetailsCarousel } from '../party-event-details-carousel'; import { ProductDetailsDescription } from '../party-event-details-description'; import { ProductDetailsReview } from '../party-event-details-review'; @@ -48,7 +48,7 @@ const SUMMARY = [ // ---------------------------------------------------------------------- type Props = { - product?: IProductItem; + product?: IPartyEventItem; loading?: boolean; error?: any; }; diff --git a/03_source/frontend/src/sections/party-event/view/party-event-edit-view.tsx b/03_source/frontend/src/sections/party-event/view/party-event-edit-view.tsx index d2439e9..3695568 100644 --- a/03_source/frontend/src/sections/party-event/view/party-event-edit-view.tsx +++ b/03_source/frontend/src/sections/party-event/view/party-event-edit-view.tsx @@ -1,13 +1,13 @@ import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs'; import { DashboardContent } from 'src/layouts/dashboard'; import { paths } from 'src/routes/paths'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { ProductNewEditForm } from '../party-event-new-edit-form'; // ---------------------------------------------------------------------- type Props = { - product?: IProductItem; + product?: IPartyEventItem; }; export function PartyEventEditView({ product }: Props) { diff --git a/03_source/frontend/src/sections/party-event/view/party-event-list-view.tsx b/03_source/frontend/src/sections/party-event/view/party-event-list-view.tsx index b617fca..1bee4f8 100644 --- a/03_source/frontend/src/sections/party-event/view/party-event-list-view.tsx +++ b/03_source/frontend/src/sections/party-event/view/party-event-list-view.tsx @@ -1,4 +1,5 @@ -// src/sections/product/view/product-list-view.tsx +// src/sections/party-event/view/party-event-list-view.tsx +// import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Card from '@mui/material/Card'; @@ -28,7 +29,7 @@ import { useBoolean, useSetState } from 'minimal-shared/hooks'; import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; // import { PRODUCT_STOCK_OPTIONS } from 'src/_mock'; -import { deleteProduct, useGetProducts } from 'src/actions/party-event'; +import { deletePartyEvent, useGetPartyEvents } from 'src/actions/party-event'; import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs'; import { ConfirmDialog } from 'src/components/custom-dialog'; import { EmptyContent } from 'src/components/empty-content'; @@ -38,7 +39,7 @@ import { DashboardContent } from 'src/layouts/dashboard'; import { endpoints } from 'src/lib/axios'; import { RouterLink } from 'src/routes/components'; import { paths } from 'src/routes/paths'; -import type { IProductItem, IProductTableFilters } from 'src/types/party-event'; +import type { IPartyEventItem, IProductTableFilters } from 'src/types/party-event'; import { mutate } from 'swr'; import { ProductTableFiltersResult } from '../party-event-table-filters-result'; import { @@ -48,7 +49,7 @@ import { RenderCellPublish, RenderCellStock, } from '../party-event-table-row'; -import { ProductTableToolbar } from '../party-event-table-toolbar'; +import { PartyEventTableToolbar } from '../party-event-table-toolbar'; // ---------------------------------------------------------------------- @@ -79,9 +80,9 @@ export function PartyEventListView() { const confirmDeleteSingleItemDialog = useBoolean(); const [idToDelete, setIdToDelete] = useState(null); - const { products, productsLoading } = useGetProducts(); + const { partyEvents, partyEventsLoading } = useGetPartyEvents(); - const [tableData, setTableData] = useState(products); + const [tableData, setTableData] = useState(partyEvents); const [selectedRowIds, setSelectedRowIds] = useState([]); const [filterButtonEl, setFilterButtonEl] = useState(null); @@ -92,10 +93,10 @@ export function PartyEventListView() { useState(HIDE_COLUMNS); useEffect(() => { - if (products.length) { - setTableData(products); + if (partyEvents.length) { + setTableData(partyEvents); } - }, [products]); + }, [partyEvents]); const canReset = currentFilters.publish.length > 0 || currentFilters.stock.length > 0; @@ -109,7 +110,7 @@ export function PartyEventListView() { try { if (idToDelete) { - await deleteProduct(idToDelete); + await deletePartyEvent(idToDelete); toast.success('Delete success!'); } } catch (error) { @@ -125,10 +126,10 @@ export function PartyEventListView() { const handleDeleteRow = useCallback( async (id: string) => { try { - await deleteProduct(id); + await deletePartyEvent(id); // invalidate cache to reload list - await mutate(endpoints.product.list); + await mutate(endpoints.partyEvent.list); toast.success('Delete success!'); } catch (error) { @@ -167,12 +168,15 @@ export function PartyEventListView() { { field: 'category', headerName: t('Category'), filterable: false }, { field: 'name', - headerName: t('Product'), + headerName: t('Party Event'), flex: 1, minWidth: 360, hideable: false, renderCell: (params) => ( - + ), }, { @@ -220,13 +224,13 @@ export function PartyEventListView() { showInMenu icon={} label="View" - href={paths.dashboard.product.details(params.row.id)} + href={paths.dashboard.partyEvent.details(params.row.id)} />, } label="Edit" - href={paths.dashboard.product.edit(params.row.id)} + href={paths.dashboard.partyEvent.edit(params.row.id)} />, Are you sure want to delete {selectedRowIds.length} items? @@ -277,7 +281,7 @@ export function PartyEventListView() { Are you sure want to delete item?} action={ } sx={{ mb: { xs: 3, md: 5 } }} @@ -333,7 +337,7 @@ export function PartyEventListView() { disableRowSelectionOnClick rows={dataFiltered} columns={columns} - loading={productsLoading} + loading={partyEventsLoading} getRowHeight={() => 'auto'} pageSizeOptions={[5, 10, 20, { value: -1, label: 'All' }]} initialState={{ pagination: { paginationModel: { pageSize: 10 } } }} @@ -402,7 +406,7 @@ function CustomToolbar({ return ( <> - @@ -474,7 +478,7 @@ export function GridActionsLinkItem({ ref, href, label, icon, sx }: GridActionsL // ---------------------------------------------------------------------- type ApplyFilterProps = { - inputData: IProductItem[]; + inputData: IPartyEventItem[]; filters: IProductTableFilters; }; @@ -482,11 +486,11 @@ function applyFilter({ inputData, filters }: ApplyFilterProps) { const { stock, publish } = filters; if (stock.length) { - inputData = inputData.filter((product) => stock.includes(product.inventoryType)); + inputData = inputData.filter((partyEvent) => stock.includes(partyEvent.inventoryType)); } if (publish.length) { - inputData = inputData.filter((product) => publish.includes(product.publish)); + inputData = inputData.filter((partyEvent) => publish.includes(partyEvent.publish)); } return inputData; diff --git a/03_source/frontend/src/sections/party-event/view/party-event-shop-details-view.tsx b/03_source/frontend/src/sections/party-event/view/party-event-shop-details-view.tsx index 25956c0..4da0428 100644 --- a/03_source/frontend/src/sections/party-event/view/party-event-shop-details-view.tsx +++ b/03_source/frontend/src/sections/party-event/view/party-event-shop-details-view.tsx @@ -15,7 +15,7 @@ import { EmptyContent } from 'src/components/empty-content'; import { Iconify } from 'src/components/iconify'; import { RouterLink } from 'src/routes/components'; import { paths } from 'src/routes/paths'; -import type { IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem } from 'src/types/party-event'; import { useCheckoutContext } from '../../checkout/context'; import { CartIcon } from '../cart-icon'; import { ProductDetailsCarousel } from '../party-event-details-carousel'; @@ -47,7 +47,7 @@ const SUMMARY = [ // ---------------------------------------------------------------------- type Props = { - product?: IProductItem; + product?: IPartyEventItem; loading?: boolean; error?: any; }; diff --git a/03_source/frontend/src/sections/party-event/view/party-event-shop-view.tsx b/03_source/frontend/src/sections/party-event/view/party-event-shop-view.tsx index 0ac3ec0..8d63025 100644 --- a/03_source/frontend/src/sections/party-event/view/party-event-shop-view.tsx +++ b/03_source/frontend/src/sections/party-event/view/party-event-shop-view.tsx @@ -14,19 +14,19 @@ import { } from 'src/_mock'; import { EmptyContent } from 'src/components/empty-content'; import { paths } from 'src/routes/paths'; -import type { IProductFilters, IProductItem } from 'src/types/party-event'; +import type { IPartyEventItem, IProductFilters } from 'src/types/party-event'; import { useCheckoutContext } from '../../checkout/context'; import { CartIcon } from '../cart-icon'; import { ProductFiltersDrawer } from '../party-event-filters-drawer'; import { ProductFiltersResult } from '../party-event-filters-result'; -import { ProductList } from '../party-event-list'; +import { PartyEventList } from '../party-event-list'; import { ProductSearch } from '../party-event-search'; import { ProductSort } from '../party-event-sort'; // ---------------------------------------------------------------------- type Props = { - products: IProductItem[]; + products: IPartyEventItem[]; loading?: boolean; }; @@ -121,7 +121,7 @@ export function ProductShopView({ products, loading }: Props) { {notFound || isEmpty ? ( renderNotFound() ) : ( - + )} ); @@ -132,7 +132,7 @@ export function ProductShopView({ products, loading }: Props) { type ApplyFilterProps = { sortBy: string; filters: IProductFilters; - inputData: IProductItem[]; + inputData: IPartyEventItem[]; }; function applyFilter({ inputData, filters, sortBy }: ApplyFilterProps) { diff --git a/03_source/frontend/src/types/party-event.ts b/03_source/frontend/src/types/party-event.ts index 60c3569..292fb7f 100644 --- a/03_source/frontend/src/types/party-event.ts +++ b/03_source/frontend/src/types/party-event.ts @@ -27,7 +27,7 @@ export type IProductReview = { attachments?: string[]; }; -export type IProductItem = { +export type IPartyEventItem = { id: string; createdAt: IDateValue; //