From 06be87f0ece7891b5c141b3bb0718dc1ddfa2a48 Mon Sep 17 00:00:00 2001 From: Vlad Chikalkin Date: Thu, 20 Feb 2025 18:11:28 +0300 Subject: [PATCH] Feature/records (#22) * components/profile: rename components files * components/profile: organize files & folders * split DataCard to 2 components * [2] components/profile: organize files & folders * data-card: fix phone field disabled * fix card header color * add schedule button for master * fix navigation & profile background * add basic schedule page * fix bottom navbar overflows content * header: remove bottom margin * replace vanilla calendar with shadcn/ui one * add slot functional * fix forbidden error * add slot operations * show slots * filter by selected day * add hook useSlots fix update slots list after add slot fix initial fetch slots * use slots hooks * split edit-slot-form into files * rename /time-slots -> /components * refactor components & folders structure * add feature: delete slot * hooks/slot: update query keys * add hooks/profile * add hook useProfileMutation * use useProfileMutation hook for update role * rename useProfile -> useProfileQuery * fix useProfileQuery queryKey * add hook useContactsQuery * remove unused ternary operator * header: add backdrop blur * create slot cards * fix elements y center * fix getSlots filters * ui/ux improvements * fix date time types & names * move profile components from sub folder * add basic slot page * fix add slot form padding x * add slot buttons * extend slot card information * fix import type * use Container in pages * change orange -> yellow for dark * use Loading spinner in slots list * refactor \components\schedule dir structure * add orders list * change query & mutation keys * change url /profile/schedule/slot/ -> /slots/ * order: show services * remove prefetchQuery * bring the results of queries and hooks into a single form * react query: globally show error toast * add font inter * fix header: center text * orders: add sorting * order card: add avatar * rename records -> orders * reduced text size * fix slot buttons * fix datetime card ui * fix header: center text (finally) * layout/container: last:mb-4 * fix type * slot-datetime: use ReadonlyTimeRange * rename files & components * remove unnecessary context using * feature: edit slot time * fix: selected day reset after go back to /schedule * rename AddTimeRange -> EditableTimeRangeForm & refactor * fix some elements on page before data loaded * fix text size * slot-card: remove gap * slot-date: remove margin * fix slots & orders layout * toast: show error text in ui --- apps/bot/src/index.ts | 13 +- apps/web/actions/contacts.ts | 12 +- apps/web/actions/orders.ts | 4 + apps/web/actions/profile.ts | 13 +- apps/web/actions/slots.ts | 60 ++++++ apps/web/app/(main)/contacts/page.tsx | 2 +- apps/web/app/(main)/layout.tsx | 2 +- apps/web/app/(main)/orders/add/page.tsx | 3 + apps/web/app/(main)/orders/page.tsx | 3 + .../app/(main)/profile/[telegramId]/page.tsx | 14 +- apps/web/app/(main)/profile/page.tsx | 15 +- .../app/(main)/profile/schedule/layout.tsx | 6 + apps/web/app/(main)/profile/schedule/page.tsx | 15 ++ .../schedule/slots/[documentId]/page.tsx | 23 +++ apps/web/app/(main)/records/add/page.tsx | 3 - apps/web/app/(main)/records/page.tsx | 3 - apps/web/app/layout.tsx | 23 ++- apps/web/components/common/divider.tsx | 13 ++ .../components/contacts/dropdown-filter.tsx | 2 +- apps/web/components/layout/container.tsx | 9 + apps/web/components/layout/index.ts | 1 + .../components/navigation/header/index.tsx | 5 +- .../navigation/header/page-title.tsx | 5 - .../components/navigation/navbar/index.tsx | 6 +- .../profile/components/card-header.tsx | 12 ++ .../checkbox-field.tsx} | 0 .../components/profile/components/index.ts | 4 + .../profile/components/link-button.tsx | 21 +++ .../text-field.tsx} | 2 +- apps/web/components/profile/data-card.tsx | 58 ++++++ apps/web/components/profile/index.ts | 3 + apps/web/components/profile/lib/actions.ts | 9 - apps/web/components/profile/links-card.tsx | 23 +++ apps/web/components/profile/person-card.tsx | 29 +++ apps/web/components/profile/profile-card.tsx | 113 ----------- apps/web/components/profile/types.tsx | 3 + apps/web/components/schedule/calendar.tsx | 23 +++ .../schedule/components/order-card.tsx | 76 ++++++++ .../schedule/components/slot-card.tsx | 66 +++++++ .../schedule/components/slot-date.tsx | 17 ++ .../schedule/components/slot-time.tsx | 73 ++++++++ .../schedule/components/time-range.tsx | 69 +++++++ .../web/components/schedule/context/index.tsx | 45 +++++ .../components/schedule/day-slot-add-form.tsx | 42 +++++ .../components/schedule/day-slots-list.tsx | 20 ++ apps/web/components/schedule/index.ts | 6 + apps/web/components/schedule/slot-buttons.tsx | 69 +++++++ .../web/components/schedule/slot-datetime.tsx | 17 ++ .../components/schedule/slot-orders-list.tsx | 18 ++ apps/web/components/schedule/types/index.tsx | 6 + apps/web/context/schedule.tsx | 17 ++ apps/web/hooks/contacts/index.ts | 1 + apps/web/hooks/contacts/query.ts | 8 + .../hooks/contacts/use-customer-contacts.ts | 18 +- apps/web/hooks/orders/index.ts | 18 ++ apps/web/hooks/profile/index.ts | 21 +++ apps/web/hooks/slots/index.ts | 67 +++++++ apps/web/package.json | 1 + apps/web/providers/error.tsx | 11 ++ apps/web/providers/query.tsx | 21 ++- apps/web/utils/context.tsx | 15 ++ apps/web/utils/date/index.ts | 35 ++++ packages/graphql/api/auth.ts | 4 +- packages/graphql/api/customer.ts | 12 +- packages/graphql/api/index.ts | 2 + packages/graphql/api/order.ts | 12 ++ packages/graphql/api/slot.ts | 48 +++++ packages/graphql/operations/order.graphql | 22 +++ packages/graphql/operations/slot.graphql | 41 ++++ .../graphql/types/operations.generated.ts | 175 +++++++++++++++--- packages/ui/package.json | 8 +- packages/ui/src/components/ui/badge.tsx | 30 +++ packages/ui/src/components/ui/calendar.tsx | 75 ++++++++ packages/ui/src/components/ui/sonner.tsx | 31 ++++ pnpm-lock.yaml | 52 +++++- 75 files changed, 1586 insertions(+), 238 deletions(-) create mode 100644 apps/web/actions/orders.ts create mode 100644 apps/web/actions/slots.ts create mode 100644 apps/web/app/(main)/orders/add/page.tsx create mode 100644 apps/web/app/(main)/orders/page.tsx create mode 100644 apps/web/app/(main)/profile/schedule/layout.tsx create mode 100644 apps/web/app/(main)/profile/schedule/page.tsx create mode 100644 apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx delete mode 100644 apps/web/app/(main)/records/add/page.tsx delete mode 100644 apps/web/app/(main)/records/page.tsx create mode 100644 apps/web/components/common/divider.tsx create mode 100644 apps/web/components/layout/container.tsx create mode 100644 apps/web/components/layout/index.ts delete mode 100644 apps/web/components/navigation/header/page-title.tsx create mode 100644 apps/web/components/profile/components/card-header.tsx rename apps/web/components/profile/{checkbox-with-text.tsx => components/checkbox-field.tsx} (100%) create mode 100644 apps/web/components/profile/components/index.ts create mode 100644 apps/web/components/profile/components/link-button.tsx rename apps/web/components/profile/{profile-field.tsx => components/text-field.tsx} (98%) create mode 100644 apps/web/components/profile/data-card.tsx create mode 100644 apps/web/components/profile/index.ts delete mode 100644 apps/web/components/profile/lib/actions.ts create mode 100644 apps/web/components/profile/links-card.tsx create mode 100644 apps/web/components/profile/person-card.tsx delete mode 100644 apps/web/components/profile/profile-card.tsx create mode 100644 apps/web/components/profile/types.tsx create mode 100644 apps/web/components/schedule/calendar.tsx create mode 100644 apps/web/components/schedule/components/order-card.tsx create mode 100644 apps/web/components/schedule/components/slot-card.tsx create mode 100644 apps/web/components/schedule/components/slot-date.tsx create mode 100644 apps/web/components/schedule/components/slot-time.tsx create mode 100644 apps/web/components/schedule/components/time-range.tsx create mode 100644 apps/web/components/schedule/context/index.tsx create mode 100644 apps/web/components/schedule/day-slot-add-form.tsx create mode 100644 apps/web/components/schedule/day-slots-list.tsx create mode 100644 apps/web/components/schedule/index.ts create mode 100644 apps/web/components/schedule/slot-buttons.tsx create mode 100644 apps/web/components/schedule/slot-datetime.tsx create mode 100644 apps/web/components/schedule/slot-orders-list.tsx create mode 100644 apps/web/components/schedule/types/index.tsx create mode 100644 apps/web/context/schedule.tsx create mode 100644 apps/web/hooks/contacts/query.ts create mode 100644 apps/web/hooks/orders/index.ts create mode 100644 apps/web/hooks/profile/index.ts create mode 100644 apps/web/hooks/slots/index.ts create mode 100644 apps/web/providers/error.tsx create mode 100644 apps/web/utils/context.tsx create mode 100644 apps/web/utils/date/index.ts create mode 100644 packages/graphql/api/order.ts create mode 100644 packages/graphql/api/slot.ts create mode 100644 packages/graphql/operations/order.graphql create mode 100644 packages/graphql/operations/slot.graphql create mode 100644 packages/ui/src/components/ui/badge.tsx create mode 100644 packages/ui/src/components/ui/calendar.tsx create mode 100644 packages/ui/src/components/ui/sonner.tsx diff --git a/apps/bot/src/index.ts b/apps/bot/src/index.ts index 76562c2..2e9c648 100644 --- a/apps/bot/src/index.ts +++ b/apps/bot/src/index.ts @@ -16,7 +16,8 @@ import { message } from 'telegraf/filters'; const bot = new Telegraf(environment.BOT_TOKEN); bot.start(async (context) => { - const customer = await getCustomer({ telegramId: context.from.id }); + const data = await getCustomer({ telegramId: context.from.id }); + const customer = data?.data?.customers?.at(0); if (customer) { return context.reply( @@ -33,7 +34,8 @@ bot.start(async (context) => { }); bot.command('addcontact', async (context) => { - const customer = await getCustomer({ telegramId: context.from.id }); + const data = await getCustomer({ telegramId: context.from.id }); + const customer = data?.data?.customers?.at(0); if (!customer) { return context.reply( @@ -50,7 +52,8 @@ bot.command('addcontact', async (context) => { }); bot.command('becomemaster', async (context) => { - const customer = await getCustomer({ telegramId: context.from.id }); + const data = await getCustomer({ telegramId: context.from.id }); + const customer = data?.data?.customers?.at(0); if (!customer) { return context.reply('Сначала поделитесь своим номером телефона.', KEYBOARD_SHARE_PHONE); @@ -73,7 +76,9 @@ bot.command('becomemaster', async (context) => { }); bot.on(message('contact'), async (context) => { - const customer = await getCustomer({ telegramId: context.from.id }); + const data = await getCustomer({ telegramId: context.from.id }); + const customer = data?.data?.customers?.at(0); + const isRegistration = !customer; const { contact } = context.message; diff --git a/apps/web/actions/contacts.ts b/apps/web/actions/contacts.ts index 8d9f530..3b1bcf4 100644 --- a/apps/web/actions/contacts.ts +++ b/apps/web/actions/contacts.ts @@ -9,11 +9,9 @@ export async function getClients() { const { user } = session; - const getCustomerClientsResponse = await getCustomerClients({ telegramId: user?.telegramId }); + const response = await getCustomerClients({ telegramId: user?.telegramId }); - return { - clients: getCustomerClientsResponse?.clients, - }; + return response.data?.customers?.at(0); } export async function getMasters() { @@ -22,9 +20,7 @@ export async function getMasters() { const { user } = session; - const getCustomerMastersResponse = await getCustomerMasters({ telegramId: user?.telegramId }); + const response = await getCustomerMasters({ telegramId: user?.telegramId }); - return { - masters: getCustomerMastersResponse?.masters, - }; + return response.data?.customers?.at(0); } diff --git a/apps/web/actions/orders.ts b/apps/web/actions/orders.ts new file mode 100644 index 0000000..f1891b0 --- /dev/null +++ b/apps/web/actions/orders.ts @@ -0,0 +1,4 @@ +'use server'; +import * as api from '@repo/graphql/api'; + +export const getOrder = api.getOrder; diff --git a/apps/web/actions/profile.ts b/apps/web/actions/profile.ts index 7d6043b..e92a3c2 100644 --- a/apps/web/actions/profile.ts +++ b/apps/web/actions/profile.ts @@ -3,17 +3,17 @@ import { authOptions } from '@/config/auth'; import { getCustomer, updateCustomerProfile } from '@repo/graphql/api'; import { type CustomerInput, type GetCustomerQueryVariables } from '@repo/graphql/types'; import { getServerSession } from 'next-auth/next'; -import { revalidatePath } from 'next/cache'; export async function getProfile(input?: GetCustomerQueryVariables) { const session = await getServerSession(authOptions); if (!session) throw new Error('Missing session'); const { user } = session; - const telegramId = input?.telegramId || user?.telegramId; - const customer = await getCustomer({ telegramId }); + const { data } = await getCustomer({ telegramId }); + const customer = data?.customers?.at(0); + return customer; } @@ -23,13 +23,12 @@ export async function updateProfile(input: CustomerInput) { const { user } = session; - const customer = await getCustomer({ telegramId: user?.telegramId }); + const { data } = await getCustomer({ telegramId: user?.telegramId }); + const customer = data.customers.at(0); if (!customer) throw new Error('Customer not found'); await updateCustomerProfile({ data: input, - documentId: customer.documentId, + documentId: customer?.documentId, }); - - revalidatePath('/profile'); } diff --git a/apps/web/actions/slots.ts b/apps/web/actions/slots.ts new file mode 100644 index 0000000..b2b440b --- /dev/null +++ b/apps/web/actions/slots.ts @@ -0,0 +1,60 @@ +'use server'; +// eslint-disable-next-line sonarjs/no-internal-api-use +import type * as ApolloTypes from '../../../packages/graphql/node_modules/@apollo/client/core'; +import { getProfile } from './profile'; +import { formatDate, formatTime } from '@/utils/date'; +import * as api from '@repo/graphql/api'; +import type * as GQL from '@repo/graphql/types'; + +type AddSlotInput = Omit; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type FixTypescriptCringe = ApolloTypes.FetchResult; + +export async function addSlot(input: AddSlotInput) { + const customer = await getProfile(); + + return api.createSlot({ + ...input, + date: formatDate(input.date).db(), + master: customer?.documentId, + time_end: formatTime(input.time_end).db(), + time_start: formatTime(input.time_start).db(), + }); +} + +export async function getSlots(input: GQL.GetSlotsQueryVariables) { + const customer = await getProfile(); + + if (!customer?.documentId) throw new Error('Customer not found'); + + return api.getSlots({ + filters: { + ...input.filters, + master: { + documentId: { + eq: customer.documentId, + }, + }, + }, + }); +} + +export async function updateSlot(input: GQL.UpdateSlotMutationVariables) { + const customer = await getProfile(); + + if (!customer?.documentId) throw new Error('Customer not found'); + + return api.updateSlot({ + ...input, + data: { + ...input.data, + date: input.data?.date ? formatDate(input.data.date).db() : undefined, + time_end: input.data?.time_end ? formatTime(input.data.time_end).db() : undefined, + time_start: input.data?.time_start ? formatTime(input.data.time_start).db() : undefined, + }, + }); +} + +export const getSlot = api.getSlot; +export const deleteSlot = api.deleteSlot; diff --git a/apps/web/app/(main)/contacts/page.tsx b/apps/web/app/(main)/contacts/page.tsx index 2bd43e6..34c2045 100644 --- a/apps/web/app/(main)/contacts/page.tsx +++ b/apps/web/app/(main)/contacts/page.tsx @@ -8,7 +8,7 @@ export default function ContactsPage() {
-

Контакты

+

Контакты

diff --git a/apps/web/app/(main)/layout.tsx b/apps/web/app/(main)/layout.tsx index b3c37f7..9369ed8 100644 --- a/apps/web/app/(main)/layout.tsx +++ b/apps/web/app/(main)/layout.tsx @@ -4,7 +4,7 @@ import { type PropsWithChildren } from 'react'; export default async function Layout({ children }: Readonly) { return ( <> -
{children}
+
{children}
); diff --git a/apps/web/app/(main)/orders/add/page.tsx b/apps/web/app/(main)/orders/add/page.tsx new file mode 100644 index 0000000..bf5b793 --- /dev/null +++ b/apps/web/app/(main)/orders/add/page.tsx @@ -0,0 +1,3 @@ +export default function AddOrdersPage() { + return 'Add Orders'; +} diff --git a/apps/web/app/(main)/orders/page.tsx b/apps/web/app/(main)/orders/page.tsx new file mode 100644 index 0000000..b339e29 --- /dev/null +++ b/apps/web/app/(main)/orders/page.tsx @@ -0,0 +1,3 @@ +export default function OrdersPage() { + return 'Orders'; +} diff --git a/apps/web/app/(main)/profile/[telegramId]/page.tsx b/apps/web/app/(main)/profile/[telegramId]/page.tsx index c94b1b4..dac16f6 100644 --- a/apps/web/app/(main)/profile/[telegramId]/page.tsx +++ b/apps/web/app/(main)/profile/[telegramId]/page.tsx @@ -1,6 +1,6 @@ -import { getProfile } from '@/actions/profile'; +import { Container } from '@/components/layout'; import { PageHeader } from '@/components/navigation'; -import { ProfileCard } from '@/components/profile/profile-card'; +import { ContactDataCard, PersonCard } from '@/components/profile'; import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'; type Props = { params: Promise<{ telegramId: string }> }; @@ -11,15 +11,13 @@ export default async function ProfilePage(props: Readonly) { const queryClient = new QueryClient(); - await queryClient.prefetchQuery({ - queryFn: () => getProfile({ telegramId }), - queryKey: telegramId ? ['profile', 'telegramId', telegramId] : ['profile'], - }); - return ( - + + + + ); } diff --git a/apps/web/app/(main)/profile/page.tsx b/apps/web/app/(main)/profile/page.tsx index 1fbf2a9..372caa5 100644 --- a/apps/web/app/(main)/profile/page.tsx +++ b/apps/web/app/(main)/profile/page.tsx @@ -1,18 +1,17 @@ -import { getProfile } from '@/actions/profile'; -import { ProfileCard } from '@/components/profile/profile-card'; +import { Container } from '@/components/layout'; +import { LinksCard, PersonCard, ProfileDataCard } from '@/components/profile'; import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'; export default async function ProfilePage() { const queryClient = new QueryClient(); - await queryClient.prefetchQuery({ - queryFn: () => getProfile(), - queryKey: ['profile'], - }); - return ( - + + + + + ); } diff --git a/apps/web/app/(main)/profile/schedule/layout.tsx b/apps/web/app/(main)/profile/schedule/layout.tsx new file mode 100644 index 0000000..4e7490d --- /dev/null +++ b/apps/web/app/(main)/profile/schedule/layout.tsx @@ -0,0 +1,6 @@ +import { ScheduleContextProvider } from '@/context/schedule'; +import { type PropsWithChildren } from 'react'; + +export default async function Layout({ children }: Readonly) { + return {children}; +} diff --git a/apps/web/app/(main)/profile/schedule/page.tsx b/apps/web/app/(main)/profile/schedule/page.tsx new file mode 100644 index 0000000..dc86121 --- /dev/null +++ b/apps/web/app/(main)/profile/schedule/page.tsx @@ -0,0 +1,15 @@ +import { Container } from '@/components/layout'; +import { PageHeader } from '@/components/navigation'; +import { DaySlotsList, ScheduleCalendar } from '@/components/schedule'; + +export default function SchedulePage() { + return ( + <> + + + + + + + ); +} diff --git a/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx b/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx new file mode 100644 index 0000000..c7eaf20 --- /dev/null +++ b/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx @@ -0,0 +1,23 @@ +import { Container } from '@/components/layout'; +import { PageHeader } from '@/components/navigation'; +import { SlotButtons, SlotDateTime, SlotOrdersList } from '@/components/schedule'; +import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'; + +type Props = { params: Promise<{ documentId: string }> }; + +export default async function ProfilePage(props: Readonly) { + const parameters = await props.params; + + const queryClient = new QueryClient(); + + return ( + + + + + + + + + ); +} diff --git a/apps/web/app/(main)/records/add/page.tsx b/apps/web/app/(main)/records/add/page.tsx deleted file mode 100644 index 4b8196a..0000000 --- a/apps/web/app/(main)/records/add/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function AddRecordsPage() { - return 'Add Records'; -} diff --git a/apps/web/app/(main)/records/page.tsx b/apps/web/app/(main)/records/page.tsx deleted file mode 100644 index 061b3a7..0000000 --- a/apps/web/app/(main)/records/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function RecordsPage() { - return 'Records'; -} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 6c91944..e083a00 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,12 +1,17 @@ import { AuthProvider } from '@/providers/auth'; +import { ErrorProvider } from '@/providers/error'; import { QueryProvider } from '@/providers/query'; import { ThemeProvider } from '@/providers/theme-provider'; import { I18nProvider } from '@/utils/i18n/provider'; import '@repo/ui/globals.css'; +import { cn } from '@repo/ui/lib/utils'; import { type Metadata } from 'next'; import { getLocale } from 'next-intl/server'; +import { Inter } from 'next/font/google'; import { type PropsWithChildren } from 'react'; +const inter = Inter({ subsets: ['latin', 'cyrillic'] }); + export const metadata: Metadata = { title: 'Запишись.онлайн', }; @@ -16,14 +21,16 @@ export default async function RootLayout({ children }: Readonly - - - - - {children} - - - + + + + + + {children} + + + + ); diff --git a/apps/web/components/common/divider.tsx b/apps/web/components/common/divider.tsx new file mode 100644 index 0000000..569f7b1 --- /dev/null +++ b/apps/web/components/common/divider.tsx @@ -0,0 +1,13 @@ +import { cn } from '@repo/ui/lib/utils'; + +type Props = { + readonly className?: string; +}; + +export function HorizontalDivider({ className }: Props) { + return ( +
+
+
+ ); +} diff --git a/apps/web/components/contacts/dropdown-filter.tsx b/apps/web/components/contacts/dropdown-filter.tsx index 62645f9..bc29eda 100644 --- a/apps/web/components/contacts/dropdown-filter.tsx +++ b/apps/web/components/contacts/dropdown-filter.tsx @@ -10,7 +10,7 @@ import { import { ChevronDown } from 'lucide-react'; import { use } from 'react'; -const filterLabels: Record = { +const filterLabels: Order = { all: 'Все', clients: 'Клиенты', masters: 'Мастера', diff --git a/apps/web/components/layout/container.tsx b/apps/web/components/layout/container.tsx new file mode 100644 index 0000000..3c339f0 --- /dev/null +++ b/apps/web/components/layout/container.tsx @@ -0,0 +1,9 @@ +import { cn } from '@repo/ui/lib/utils'; +import { type PropsWithChildren } from 'react'; + +export function Container({ + children, + className, +}: Readonly & { readonly className?: string }) { + return
{children}
; +} diff --git a/apps/web/components/layout/index.ts b/apps/web/components/layout/index.ts new file mode 100644 index 0000000..85ee15b --- /dev/null +++ b/apps/web/components/layout/index.ts @@ -0,0 +1 @@ +export * from './container'; diff --git a/apps/web/components/navigation/header/index.tsx b/apps/web/components/navigation/header/index.tsx index 1dbc698..21424e9 100644 --- a/apps/web/components/navigation/header/index.tsx +++ b/apps/web/components/navigation/header/index.tsx @@ -1,14 +1,13 @@ 'use client'; import { BackButton } from './back-button'; -import { PageTitle } from './page-title'; type Props = { title: string | undefined }; export function PageHeader(props: Readonly) { return ( -
+
- + {props.title}
); } diff --git a/apps/web/components/navigation/header/page-title.tsx b/apps/web/components/navigation/header/page-title.tsx deleted file mode 100644 index 967c468..0000000 --- a/apps/web/components/navigation/header/page-title.tsx +++ /dev/null @@ -1,5 +0,0 @@ -type Props = { readonly title: string | undefined }; - -export function PageTitle(props: Readonly) { - return {props?.title}; -} diff --git a/apps/web/components/navigation/navbar/index.tsx b/apps/web/components/navigation/navbar/index.tsx index 380c1af..fcb25e4 100644 --- a/apps/web/components/navigation/navbar/index.tsx +++ b/apps/web/components/navigation/navbar/index.tsx @@ -10,11 +10,11 @@ export function BottomNav() { if (!isFirstLevel) return null; return ( -