From c879a7ec035bede9412e6e2fa92ac6dd2987b937 Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Sun, 17 Nov 2024 12:26:55 +0100 Subject: [PATCH 1/3] refactor(www): use new trpc root provider --- apps/www/app/(auth)/signup/student/page.tsx | 5 +- .../(public)/following/_client/List.tsx | 2 +- .../(main)/exchanges/@categories/Filter.tsx | 5 +- apps/www/app/(main)/exchanges/layout.tsx | 17 +- apps/www/app/(main)/exchanges/page.tsx | 6 +- apps/www/app/(main)/navbar.tsx | 4 +- .../navbar/notification_indicator.client.tsx | 18 +-- .../components/shell/AuthSessionProvider.tsx | 3 + apps/www/components/shell/RootProviders.tsx | 4 +- .../exchanges/filter}/Exchanges_Filter.tsx | 0 apps/www/widgets/exchanges/filter/index.ts | 3 + .../exchanges/list}/List.tsx | 8 +- .../exchanges/list}/SearchForm.tsx | 0 apps/www/widgets/exchanges/list/index.ts | 4 + .../infra/database/seeding/inbox/greetings.ts | 35 +++++ packages/@1/infra/database/seeding/index.ts | 1 + packages/@1/infra/database/testing/index.ts | 16 ++ packages/@1/modules/exchange/api/src/index.ts | 27 ++-- .../exchange/api/src/public/by_id.e2e.test.ts | 35 +---- .../modules/exchange/api/src/public/by_id.ts | 98 ++++++------ .../exchange/api/src/public/find.e2e.test.ts | 40 ++--- .../modules/exchange/api/src/public/find.ts | 148 +++++++++--------- .../notification/api/src/count_unread.ts | 76 --------- .../count_unread.e2e.test.ts.snap | 7 + .../src/count_unread/count_unread.e2e.test.ts | 131 ++++++++++++++++ .../api/src/count_unread/count_unread.ts | 78 +++++++++ .../api/src/count_unread/index.ts | 3 + .../@1/modules/notification/api/src/find.ts | 93 ----------- .../find/__snapshots__/find.e2e.test.ts.snap | 29 ++++ .../api/src/find/find.e2e.test.ts | 57 +++++++ .../modules/notification/api/src/find/find.ts | 81 ++++++++++ .../notification/api/src/find/index.ts | 3 + .../@1/modules/notification/api/src/index.ts | 14 +- packages/@1/modules/trpc/src/testing/index.ts | 13 ++ serkels.code-workspace | 11 ++ 35 files changed, 677 insertions(+), 398 deletions(-) rename apps/www/{app/(main)/exchanges/_client => widgets/exchanges/filter}/Exchanges_Filter.tsx (100%) create mode 100644 apps/www/widgets/exchanges/filter/index.ts rename apps/www/{app/(main)/exchanges/_client => widgets/exchanges/list}/List.tsx (93%) rename apps/www/{app/(main)/exchanges/_client => widgets/exchanges/list}/SearchForm.tsx (100%) create mode 100644 apps/www/widgets/exchanges/list/index.ts create mode 100644 packages/@1/infra/database/seeding/inbox/greetings.ts delete mode 100644 packages/@1/modules/notification/api/src/count_unread.ts create mode 100644 packages/@1/modules/notification/api/src/count_unread/__snapshots__/count_unread.e2e.test.ts.snap create mode 100644 packages/@1/modules/notification/api/src/count_unread/count_unread.e2e.test.ts create mode 100644 packages/@1/modules/notification/api/src/count_unread/count_unread.ts create mode 100644 packages/@1/modules/notification/api/src/count_unread/index.ts delete mode 100644 packages/@1/modules/notification/api/src/find.ts create mode 100644 packages/@1/modules/notification/api/src/find/__snapshots__/find.e2e.test.ts.snap create mode 100644 packages/@1/modules/notification/api/src/find/find.e2e.test.ts create mode 100644 packages/@1/modules/notification/api/src/find/find.ts create mode 100644 packages/@1/modules/notification/api/src/find/index.ts diff --git a/apps/www/app/(auth)/signup/student/page.tsx b/apps/www/app/(auth)/signup/student/page.tsx index 5bbafed62..dd43dbaa5 100644 --- a/apps/www/app/(auth)/signup/student/page.tsx +++ b/apps/www/app/(auth)/signup/student/page.tsx @@ -1,6 +1,5 @@ // -import { TrpcRootProvider } from ":trpc/root"; import { TRPC_SSR } from ":trpc/server"; import Form from ":widgets/auth/SignUpForm"; import { auth } from "@1.modules/auth.next"; @@ -38,9 +37,7 @@ async function Page() { return (
- -
- +
); } diff --git a/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx b/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx index 087df98ce..ef49a6dec 100644 --- a/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx @@ -2,6 +2,7 @@ import { ProfileAvatarMedia } from ":components/avatar"; import type { inferInfiniteQueryObserverSuccessResult } from ":components/inferQueryResult"; +import { Loading_Placeholder } from ":components/placeholder/Loading_Placeholder"; import { TRPC_React } from ":trpc/client"; import type { AvatarProfile } from "@1.modules/profile.domain"; import { EmptyList, LoadMoreButton } from "@1.ui/react/async"; @@ -9,7 +10,6 @@ import { button_item } from "@1.ui/react/button/atom"; import { Spinner } from "@1.ui/react/spinner"; import Link from "next/link"; import { P, match } from "ts-pattern"; -import Loading_Placeholder from "../loading"; // diff --git a/apps/www/app/(main)/exchanges/@categories/Filter.tsx b/apps/www/app/(main)/exchanges/@categories/Filter.tsx index aaf1f4207..c8a82216f 100644 --- a/apps/www/app/(main)/exchanges/@categories/Filter.tsx +++ b/apps/www/app/(main)/exchanges/@categories/Filter.tsx @@ -2,7 +2,7 @@ import { useSyncSearchQuery } from ":components/hooks/useSyncSearchQuery"; import { useAutoClose } from ":components/shell/AsideFilter.client"; -import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { CATEGORY_ALL } from "@1.modules/category.domain"; import { FilterRadioList } from "@1.ui/react/form/FilterRadioList"; import { usePathname, useRouter } from "next/navigation"; @@ -13,7 +13,8 @@ import { useMemo } from "react"; export function Filter() { const { query, setQuery } = useSyncSearchQuery("category"); const { query: filter } = useSyncSearchQuery("f"); - const { data: categories_, status } = TRPC_React.category.exchange.useQuery(); + const { data: categories_, status } = + trpc_client.category.exchange.useQuery(); const { close } = useAutoClose(); const pathname = usePathname() ?? ""; const router = useRouter(); diff --git a/apps/www/app/(main)/exchanges/layout.tsx b/apps/www/app/(main)/exchanges/layout.tsx index d6f0fb8c4..20f1affc5 100644 --- a/apps/www/app/(main)/exchanges/layout.tsx +++ b/apps/www/app/(main)/exchanges/layout.tsx @@ -1,19 +1,10 @@ /// import { AsideFilter } from ":components/shell/AsideFilter"; +import { Exchanges_Filter } from ":widgets/exchanges/filter"; +import { SearchForm } from ":widgets/exchanges/list"; import { Grid } from "@1.ui/react/grid"; -import InputSearch from "@1.ui/react/input/InputSearch"; -import dynamic from "next/dynamic"; import type { PropsWithChildren, ReactNode } from "react"; -import { Exchanges_Filter } from "./_client/Exchanges_Filter"; - -// - -const SearchForm = dynamic(() => import("./_client/SearchForm"), { - loading() { - return ; - }, -}); // @@ -37,9 +28,9 @@ export default async function Layout({ {categories}
{children}
- */} ); } diff --git a/apps/www/app/(main)/exchanges/page.tsx b/apps/www/app/(main)/exchanges/page.tsx index 8ff7d0d6a..25ec083db 100644 --- a/apps/www/app/(main)/exchanges/page.tsx +++ b/apps/www/app/(main)/exchanges/page.tsx @@ -1,8 +1,9 @@ // import { TRPC_Hydrate } from ":trpc/server"; +import { List } from ":widgets/exchanges/list"; import { trpc_server } from "@1.infra/trpc/react-query/server"; -import { getServerSession } from "@1.modules/auth.next"; +import { auth } from "@1.modules/auth.next"; import { Exchange_Filter, type ExchangeSearchParams, @@ -12,7 +13,6 @@ import { PlusBox } from "@1.ui/react/icons"; import { link } from "@1.ui/react/link/atom"; import type { Metadata, ResolvingMetadata } from "next"; import Link from "next/link"; -import List from "./_client/List"; // @@ -61,7 +61,7 @@ export default async function Page({ } async function NewExchangeSection() { - const session = await getServerSession(); + const session = await auth(); if (!session) return null; if (session.profile.role !== "STUDENT") return null; diff --git a/apps/www/app/(main)/navbar.tsx b/apps/www/app/(main)/navbar.tsx index a17982c30..e0fd2f7da 100644 --- a/apps/www/app/(main)/navbar.tsx +++ b/apps/www/app/(main)/navbar.tsx @@ -7,7 +7,7 @@ import { } from ":components/navbar/notification_indicator.client"; import { MobileNavBar } from ":components/shell/MobileNavBar"; import { TRPC_SSR } from ":trpc/server"; -import { getServerSession } from "@1.modules/auth.next"; +import { auth } from "@1.modules/auth.next"; import { PROFILE_ROLES, type AuthProfile } from "@1.modules/profile.domain"; import { Avatar } from "@1.modules/profile.ui"; import { Grid } from "@1.ui/react/grid"; @@ -40,7 +40,7 @@ export default function UserBar() { } async function UserNavGroup({ className }: ComponentPropsWithoutRef<"nav">) { - const session = await getServerSession(); + const session = await auth(); const { base, icon } = user_nav_group_variants({ size: { initial: "xsmall", diff --git a/apps/www/components/navbar/notification_indicator.client.tsx b/apps/www/components/navbar/notification_indicator.client.tsx index 6fa2f0722..654fab426 100644 --- a/apps/www/components/navbar/notification_indicator.client.tsx +++ b/apps/www/components/navbar/notification_indicator.client.tsx @@ -1,6 +1,6 @@ "use client"; -import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { useSession } from "@1.modules/auth.next/react"; import { NotificationGroup } from "@1.modules/notification.domain"; import { DotIndicator } from "@1.modules/notification.ui/DotIndicator"; @@ -11,8 +11,8 @@ import { useAsync, useUpdateEffect } from "@react-hookz/web"; export function Notification_DotIndicator() { const { status } = useSession(); - const utils = TRPC_React.useUtils(); - const { data: count_unread } = TRPC_React.notification.count_unread.useQuery( + const utils = trpc_client.useUtils(); + const { data: count_unread } = trpc_client.notification.count_unread.useQuery( {}, { enabled: status === "authenticated", @@ -43,9 +43,9 @@ export function Notification_DotIndicator() { export function MessageNews_DotIndicator() { const { status } = useSession(); - const utils = TRPC_React.useUtils(); + const utils = trpc_client.useUtils(); const { data: count_unread, dataUpdatedAt } = - TRPC_React.notification.count_unread.useQuery( + trpc_client.notification.count_unread.useQuery( { type: NotificationGroup.Enum.INBOX, }, @@ -64,9 +64,9 @@ export function MessageNews_DotIndicator() { export function ExchangeNews_DotIndicator() { const { status } = useSession(); - const utils = TRPC_React.useUtils(); + const utils = trpc_client.useUtils(); const { data: count_unread, dataUpdatedAt } = - TRPC_React.notification.count_unread.useQuery( + trpc_client.notification.count_unread.useQuery( { type: NotificationGroup.Enum.EXCHANGE, }, @@ -85,7 +85,7 @@ export function ExchangeNews_DotIndicator() { export function NewsInMessage_Indicator() { const { status } = useSession(); - const { data: count_unread } = TRPC_React.notification.count_unread.useQuery( + const { data: count_unread } = trpc_client.notification.count_unread.useQuery( { type: NotificationGroup.Enum.INBOX, }, @@ -96,7 +96,7 @@ export function NewsInMessage_Indicator() { export function NewsInExchange_Indicator() { const { status } = useSession(); - const { data: count_unread } = TRPC_React.notification.count_unread.useQuery( + const { data: count_unread } = trpc_client.notification.count_unread.useQuery( { type: NotificationGroup.Enum.EXCHANGE, }, diff --git a/apps/www/components/shell/AuthSessionProvider.tsx b/apps/www/components/shell/AuthSessionProvider.tsx index f06fb80b2..f73c178fa 100644 --- a/apps/www/components/shell/AuthSessionProvider.tsx +++ b/apps/www/components/shell/AuthSessionProvider.tsx @@ -1,9 +1,12 @@ "use client"; + import type { Session } from "@1.modules/auth.next"; import { SessionProvider } from "@1.modules/auth.next/react"; import { sendGAEvent } from "@next/third-parties/google"; import { useEffect, type PropsWithChildren } from "react"; +// + export function AuthSessionProvider({ children, session, diff --git a/apps/www/components/shell/RootProviders.tsx b/apps/www/components/shell/RootProviders.tsx index eda311e4f..e674decde 100644 --- a/apps/www/components/shell/RootProviders.tsx +++ b/apps/www/components/shell/RootProviders.tsx @@ -1,7 +1,7 @@ "use client"; import { LegalProvider } from ":components/terms/context"; -import { TrpcProvider } from ":trpc/client"; +import { TrpcRootProvider } from ":trpc/root"; import { SessionProvider } from "@1.modules/auth.next/react"; import { useMediaQuery } from "@react-hookz/web"; import { @@ -27,7 +27,7 @@ export function RootProviders({ children }: PropsWithChildren) { - {children} + {children} diff --git a/apps/www/app/(main)/exchanges/_client/Exchanges_Filter.tsx b/apps/www/widgets/exchanges/filter/Exchanges_Filter.tsx similarity index 100% rename from apps/www/app/(main)/exchanges/_client/Exchanges_Filter.tsx rename to apps/www/widgets/exchanges/filter/Exchanges_Filter.tsx diff --git a/apps/www/widgets/exchanges/filter/index.ts b/apps/www/widgets/exchanges/filter/index.ts new file mode 100644 index 000000000..f36d6ef5d --- /dev/null +++ b/apps/www/widgets/exchanges/filter/index.ts @@ -0,0 +1,3 @@ +// + +export { Exchanges_Filter } from "./Exchanges_Filter"; diff --git a/apps/www/app/(main)/exchanges/_client/List.tsx b/apps/www/widgets/exchanges/list/List.tsx similarity index 93% rename from apps/www/app/(main)/exchanges/_client/List.tsx rename to apps/www/widgets/exchanges/list/List.tsx index d73f0d4a7..1f5c6e86c 100644 --- a/apps/www/app/(main)/exchanges/_client/List.tsx +++ b/apps/www/widgets/exchanges/list/List.tsx @@ -1,8 +1,9 @@ "use client"; import type { inferInfiniteQueryObserverSuccessResult } from ":components/inferQueryResult"; -import { TRPC_React } from ":trpc/client"; +import { Loading_Placeholder } from ":components/placeholder/Loading_Placeholder"; import { Exchange_Card } from ":widgets/exchanges/card"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { useSession } from "@1.modules/auth.next/react"; import type { Entity } from "@1.modules/core/domain"; import { Exchange_Filter, type Exchange } from "@1.modules/exchange.domain"; @@ -13,7 +14,6 @@ import { useSearchParams } from "next/navigation"; import { useEffect, type ComponentProps, type ReactNode } from "react"; import { match, P } from "ts-pattern"; import type { z } from "zod"; -import Loading_Placeholder from "../loading"; // @@ -22,7 +22,7 @@ function useQueryExchanges(input: { filter: z.infer | undefined; search: string | undefined; }) { - return TRPC_React.exchanges.find.useInfiniteQuery(input, { + return trpc_client.exchanges.find.useInfiniteQuery(input, { getNextPageParam: ({ next_cursor }) => next_cursor, keepPreviousData: true, }); @@ -116,7 +116,7 @@ function Item({ id }: Entity) { // function useQueryExchangeById(id: string) { - return TRPC_React.exchanges.by_id.useQuery(id); + return trpc_client.exchanges.by_id.useQuery(id); } function Exchange_byId({ diff --git a/apps/www/app/(main)/exchanges/_client/SearchForm.tsx b/apps/www/widgets/exchanges/list/SearchForm.tsx similarity index 100% rename from apps/www/app/(main)/exchanges/_client/SearchForm.tsx rename to apps/www/widgets/exchanges/list/SearchForm.tsx diff --git a/apps/www/widgets/exchanges/list/index.ts b/apps/www/widgets/exchanges/list/index.ts new file mode 100644 index 000000000..23d98aa2c --- /dev/null +++ b/apps/www/widgets/exchanges/list/index.ts @@ -0,0 +1,4 @@ +// + +export { default as List } from "./List"; +export { default as SearchForm } from "./SearchForm"; diff --git a/packages/@1/infra/database/seeding/inbox/greetings.ts b/packages/@1/infra/database/seeding/inbox/greetings.ts new file mode 100644 index 000000000..175a5cb82 --- /dev/null +++ b/packages/@1/infra/database/seeding/inbox/greetings.ts @@ -0,0 +1,35 @@ +// + +import { PrismaClient } from "#prisma/client"; + +// + +export async function create_greatings_message( + prisma: PrismaClient, + author_profile_id: string, + recipient_profile_id: string, + message = "Bonjour", +) { + await prisma.notification.create({ + data: { + created_at: new Date(), + id: "greatings_notification_id", + inbox_message: { + create: { + message: { + create: { + author: { connect: { id: recipient_profile_id } }, + content: message, + created_at: new Date(), + thread: { create: { id: "greatings_thread_id" } }, + updated_at: new Date(), + }, + }, + }, + }, + owner: { connect: { id: author_profile_id } }, + read_at: null, + type: "INBOX_NEW_MESSAGE", + }, + }); +} diff --git a/packages/@1/infra/database/seeding/index.ts b/packages/@1/infra/database/seeding/index.ts index 7f4dc9a6b..1d083d6ca 100644 --- a/packages/@1/infra/database/seeding/index.ts +++ b/packages/@1/infra/database/seeding/index.ts @@ -4,6 +4,7 @@ export * from "./category/film"; export * from "./category/masterclass"; export * from "./exchange/slap"; export * from "./exchange/the_creator"; +export * from "./inbox/greetings"; export * from "./opportunity/concert_20240915"; export * from "./partner/vulfpeck"; export * from "./studient/douglas"; diff --git a/packages/@1/infra/database/testing/index.ts b/packages/@1/infra/database/testing/index.ts index d74e55079..b7c636ff4 100644 --- a/packages/@1/infra/database/testing/index.ts +++ b/packages/@1/infra/database/testing/index.ts @@ -38,3 +38,19 @@ export async function empty_database() { await client.exec(`DROP SCHEMA public CASCADE;`); await client.exec(`CREATE SCHEMA public;`); } + +export async function database_status() { + console.log("🕵️ DATABASE STATUS"); + console.log({ + exchange_message_notification: + await prisma.exchangeMessageNotification.count(), + inbox_message_notification: await prisma.inboxMessageNotification.count(), + inbox_thread: await prisma.inboxThread.count(), + notification: await prisma.notification.count(), + profile_added_notification: await prisma.profileAddedNotification.count(), + profile: await prisma.profile.count(), + student: await prisma.student.count(), + thread: await prisma.thread.count(), + user: await prisma.user.count(), + }); +} diff --git a/packages/@1/modules/exchange/api/src/index.ts b/packages/@1/modules/exchange/api/src/index.ts index 29cbf03c6..cada983a7 100644 --- a/packages/@1/modules/exchange/api/src/index.ts +++ b/packages/@1/modules/exchange/api/src/index.ts @@ -5,11 +5,18 @@ import { Deal_Status_Schema, Exchange_Create_Schema, } from "@1.modules/exchange.domain"; -import { next_auth_procedure, procedure, router } from "@1.modules/trpc"; +import { + mergeRouters, + next_auth_procedure, + procedure, + router, +} from "@1.modules/trpc"; import { z } from "zod"; import { me } from "./me"; -import by_id from "./public/by_id"; -import find_router from "./public/find"; +import by_id_api_router from "./public/by_id"; +import find_api_router from "./public/find"; + +// const exchange_api_router = router({ // @@ -41,10 +48,6 @@ const exchange_api_router = router({ // - by_id, - - // - by_particitpant: next_auth_procedure .input( z.object({ @@ -133,11 +136,11 @@ const exchange_api_router = router({ }), // - - find: find_router, - - // }); -export default exchange_api_router; +export default mergeRouters( + by_id_api_router, + exchange_api_router, + find_api_router, +); export type ExchangeApiRouter = typeof exchange_api_router; diff --git a/packages/@1/modules/exchange/api/src/public/by_id.e2e.test.ts b/packages/@1/modules/exchange/api/src/public/by_id.e2e.test.ts index 8449f49da..01adab76a 100644 --- a/packages/@1/modules/exchange/api/src/public/by_id.e2e.test.ts +++ b/packages/@1/modules/exchange/api/src/public/by_id.e2e.test.ts @@ -8,45 +8,30 @@ import { create_slap_exchange, } from "@1.infra/database/seeding"; import prisma, { empty_database, migrate } from "@1.infra/database/testing"; -import { - create_nextauth_header, - createCallerFactory, - router, -} from "@1.modules/trpc"; -import { douglas_golden_nextauth_header } from "@1.modules/trpc/testing"; +import { createCallerFactory } from "@1.modules/trpc"; +import { douglas_student_session } from "@1.modules/trpc/testing"; import { afterEach, beforeAll, beforeEach, describe, expect, - setSystemTime, test, } from "bun:test"; -import exchange_by_id from "./by_id"; - -// - -const NEXTAUTH_SECRET = "🔑"; - -beforeAll(() => { - process.env["NEXTAUTH_SECRET"] = NEXTAUTH_SECRET; -}); +import by_id_api_router from "./by_id"; // beforeAll(empty_database); beforeAll(migrate); -beforeAll(() => { - setSystemTime(new Date("2011-11-11")); -}); // describe("visitor", () => { test("should return a sanitize exchange", async () => { - const caller = createCallerFactory(router({ by_id: exchange_by_id })); + const caller = createCallerFactory(by_id_api_router); const trpc = caller({ + auth: () => null, prisma, } as any); const exchange = await trpc.by_id("slap_exchange_id"); @@ -55,16 +40,10 @@ describe("visitor", () => { }); describe("connected studient", () => { - let nextauth_header: Awaited>; - - beforeAll(async () => { - nextauth_header = douglas_golden_nextauth_header; - }); - test("should return a sanitize exchange", async () => { - const caller = createCallerFactory(router({ by_id: exchange_by_id })); + const caller = createCallerFactory(by_id_api_router); const trpc = caller({ - headers: { ...nextauth_header }, + auth: () => douglas_student_session, prisma, } as any); const exchange = await trpc.by_id("slap_exchange_id"); diff --git a/packages/@1/modules/exchange/api/src/public/by_id.ts b/packages/@1/modules/exchange/api/src/public/by_id.ts index f57388042..354b24648 100644 --- a/packages/@1/modules/exchange/api/src/public/by_id.ts +++ b/packages/@1/modules/exchange/api/src/public/by_id.ts @@ -1,63 +1,65 @@ // import { Deal_Status_Schema } from "@1.modules/exchange.domain"; -import { maybe_next_auth_procedure } from "@1.modules/trpc"; +import { maybe_session_procedure, router } from "@1.modules/trpc"; import { z } from "zod"; // -export default maybe_next_auth_procedure - .input(z.string()) - .use(async ({ ctx: { payload, prisma }, input: id, next }) => { - const profile_id = payload.profile?.id; - const get_exchange_by_id = prisma.exchange.findUniqueOrThrow({ - include: { - category: true, - return: true, - owner: { - select: { - profile: { - select: { id: true, name: true, image: true }, +export default router({ + by_id: maybe_session_procedure + .input(z.string()) + .use(async ({ ctx: { prisma, session }, input: id, next }) => { + const profile_id = session?.profile.id; + const get_exchange_by_id = prisma.exchange.findUniqueOrThrow({ + include: { + category: true, + return: true, + owner: { + select: { + profile: { + select: { id: true, name: true, image: true }, + }, + university: true, }, - university: true, }, - }, - deals: { - select: { - id: true, - status: true, - participant: { select: { profile: { select: { id: true } } } }, + deals: { + select: { + id: true, + status: true, + participant: { select: { profile: { select: { id: true } } } }, + }, + where: { status: Deal_Status_Schema.Enum.APPROVED }, }, - where: { status: Deal_Status_Schema.Enum.APPROVED }, }, - }, - where: { id }, - }); + where: { id }, + }); - /** - * Ensure to remove participant profile information for - */ - const sanitize = async (exchange: Awaited) => { - const { deals } = exchange; - return { - ...exchange, - deals: deals.map((deal) => ({ - ...deal, - participant: - deal.participant.profile.id === profile_id - ? deal.participant - : undefined, - })), + /** + * Ensure to remove participant profile information for + */ + const sanitize = async (exchange: Awaited) => { + const { deals } = exchange; + return { + ...exchange, + deals: deals.map((deal) => ({ + ...deal, + participant: + deal.participant.profile.id === profile_id + ? deal.participant + : undefined, + })), + }; }; - }; - // + // - return next({ - ctx: { get_exchange_by_id, sanitize }, - }); - }) - .query(async ({ ctx: { get_exchange_by_id, sanitize } }) => { - const exchange = await get_exchange_by_id; - return sanitize(exchange); - }); + return next({ + ctx: { get_exchange_by_id, sanitize }, + }); + }) + .query(async ({ ctx: { get_exchange_by_id, sanitize } }) => { + const exchange = await get_exchange_by_id; + return sanitize(exchange); + }), +}); diff --git a/packages/@1/modules/exchange/api/src/public/find.e2e.test.ts b/packages/@1/modules/exchange/api/src/public/find.e2e.test.ts index 16b7124ae..1baf1d5d1 100644 --- a/packages/@1/modules/exchange/api/src/public/find.e2e.test.ts +++ b/packages/@1/modules/exchange/api/src/public/find.e2e.test.ts @@ -7,13 +7,9 @@ import { create_slap_exchange, } from "@1.infra/database/seeding"; import prisma, { empty_database, migrate } from "@1.infra/database/testing"; +import { createCallerFactory } from "@1.modules/trpc"; import { - create_nextauth_header, - createCallerFactory, - router, -} from "@1.modules/trpc"; -import { - douglas_golden_nextauth_header, + douglas_student_session, NEXTAUTH_SECRET, } from "@1.modules/trpc/testing"; import { @@ -25,7 +21,7 @@ import { setSystemTime, test, } from "bun:test"; -import find from "./find"; +import find_api_router from "./find"; // @@ -45,8 +41,8 @@ beforeAll(() => { describe("visitor", () => { test("should return latest exchanges", async () => { - const caller = createCallerFactory(router({ find })); - const trpc = caller({ prisma } as any); + const caller = createCallerFactory(find_api_router); + const trpc = caller({ auth: () => null, prisma } as any); const exchange = await trpc.find({}); expect(exchange).toMatchSnapshot(); }); @@ -56,8 +52,8 @@ describe("visitor", () => { data: { is_active: false }, where: { id: "slap_exchange_id" }, }); - const caller = createCallerFactory(router({ find })); - const trpc = caller({ prisma } as any); + const caller = createCallerFactory(find_api_router); + const trpc = caller({ auth: () => null, prisma } as any); const exchange = await trpc.find({}); expect(exchange).toMatchSnapshot(); }); @@ -67,24 +63,18 @@ describe("visitor", () => { data: { expiry_date: new Date("2011-11-10") }, where: { id: "slap_exchange_id" }, }); - const caller = createCallerFactory(router({ find })); - const trpc = caller({ prisma } as any); + const caller = createCallerFactory(find_api_router); + const trpc = caller({ auth: () => null, prisma } as any); const exchange = await trpc.find({}); expect(exchange).toMatchSnapshot(); }); }); describe("connected studient", () => { - let nextauth_header: Awaited>; - - beforeAll(async () => { - nextauth_header = douglas_golden_nextauth_header; - }); - test("should return latest exchanges", async () => { - const caller = createCallerFactory(router({ find })); + const caller = createCallerFactory(find_api_router); const trpc = caller({ - headers: { ...nextauth_header }, + auth: () => douglas_student_session, prisma, } as any); const exchange = await trpc.find({}); @@ -96,9 +86,9 @@ describe("connected studient", () => { data: { blacklist: { create: { profile_id: "joedart_profile_id" } } }, where: { id: "douglas_profile_id" }, }); - const caller = createCallerFactory(router({ find })); + const caller = createCallerFactory(find_api_router); const trpc = caller({ - headers: { ...nextauth_header }, + auth: () => douglas_student_session, prisma, } as any); const exchange = await trpc.find({}); @@ -110,9 +100,9 @@ describe("connected studient", () => { data: { blacklisted_by: { create: { owner_id: "joedart_profile_id" } } }, where: { id: "douglas_profile_id" }, }); - const caller = createCallerFactory(router({ find })); + const caller = createCallerFactory(find_api_router); const trpc = caller({ - headers: { ...nextauth_header }, + auth: () => douglas_student_session, prisma, } as any); const exchange = await trpc.find({}); diff --git a/packages/@1/modules/exchange/api/src/public/find.ts b/packages/@1/modules/exchange/api/src/public/find.ts index c5c44028a..dab65fef4 100644 --- a/packages/@1/modules/exchange/api/src/public/find.ts +++ b/packages/@1/modules/exchange/api/src/public/find.ts @@ -2,7 +2,11 @@ import type { Prisma } from "@1.infra/database"; import { Exchange_Filter } from "@1.modules/exchange.domain"; -import { maybe_next_auth_procedure, with_next_cursor } from "@1.modules/trpc"; +import { + maybe_session_procedure, + router, + with_next_cursor, +} from "@1.modules/trpc"; import { endOfYesterday } from "date-fns"; import { match, P } from "ts-pattern"; import { z } from "zod"; @@ -19,84 +23,88 @@ const input_schema = z.object({ // -export default maybe_next_auth_procedure - .input(input_schema) - .query(async ({ ctx: { payload, prisma }, input }) => { - const { limit, category, cursor, search } = input; - const nerrow = match({ payload, input }) - .with( - { payload: { profile: { role: "STUDENT" } } }, - ({ - payload: { - profile: { id: profile_id }, - }, - input: { filter }, - }) => profile_filter(profile_id, filter), - ) - .otherwise(() => ({})); +export default router({ + find: maybe_session_procedure + .input(input_schema) + .query(async ({ ctx: { session, prisma }, input }) => { + const { limit, category, cursor, search } = input; + const nerrow = match({ session, input }) + .with( + { session: { profile: { role: "STUDENT" } } }, + ({ + session: { + profile: { id: profile_id }, + }, + input: { filter }, + }) => profile_filter(profile_id, filter), + ) + .otherwise(() => ({})); - const search_where: Prisma.ExchangeWhereInput = { - OR: [ - { title: { contains: search ?? "", mode: "insensitive" } }, - { - description: { contains: search ?? "", mode: "insensitive" }, - }, - { location: { contains: search ?? "", mode: "insensitive" } }, - { - owner: { - profile: { - name: { contains: search ?? "", mode: "insensitive" }, + const search_where: Prisma.ExchangeWhereInput = { + OR: [ + { title: { contains: search ?? "", mode: "insensitive" } }, + { + description: { contains: search ?? "", mode: "insensitive" }, + }, + { location: { contains: search ?? "", mode: "insensitive" } }, + { + owner: { + profile: { + name: { contains: search ?? "", mode: "insensitive" }, + }, }, }, - }, - ], - }; + ], + }; - const active_exchanges_where: Prisma.ExchangeWhereInput = { - is_active: true, - OR: [{ expiry_date: null }, { expiry_date: { gte: endOfYesterday() } }], - }; - const category_where: Prisma.ExchangeWhereInput = category - ? { category: { slug: category } } - : {}; + const active_exchanges_where: Prisma.ExchangeWhereInput = { + is_active: true, + OR: [{ expiry_date: null }, { expiry_date: { gte: endOfYesterday() } }], + }; + const category_where: Prisma.ExchangeWhereInput = category + ? { category: { slug: category } } + : {}; - const where_not_in_profile_blacklist = match(payload.profile) - .with( - { id: P.select() }, - (profile_id): Prisma.ExchangeWhereInput => ({ - AND: [ - { owner: { profile: { blacklist: { none: { profile_id } } } } }, - { - owner: { - profile: { blacklisted_by: { none: { owner_id: profile_id } } }, + const where_not_in_profile_blacklist = match(session?.profile) + .with( + { id: P.select() }, + (profile_id): Prisma.ExchangeWhereInput => ({ + AND: [ + { owner: { profile: { blacklist: { none: { profile_id } } } } }, + { + owner: { + profile: { + blacklisted_by: { none: { owner_id: profile_id } }, + }, + }, }, - }, - ], - }), - ) - .otherwise(() => ({})); + ], + }), + ) + .otherwise(() => ({})); - const items = await prisma.exchange.findMany({ - ...(cursor ? { cursor: { id: cursor } } : {}), - orderBy: [ - { expiry_date: { sort: "asc", nulls: "last" } }, - { created_at: "desc" }, - { id: "desc" }, - ], - take: limit + 1, - where: { - AND: [ - where_not_in_profile_blacklist, - search_where, - active_exchanges_where, - category_where, - nerrow, + const items = await prisma.exchange.findMany({ + ...(cursor ? { cursor: { id: cursor } } : {}), + orderBy: [ + { expiry_date: { sort: "asc", nulls: "last" } }, + { created_at: "desc" }, + { id: "desc" }, ], - }, - }); + take: limit + 1, + where: { + AND: [ + where_not_in_profile_blacklist, + search_where, + active_exchanges_where, + category_where, + nerrow, + ], + }, + }); - return with_next_cursor(limit, items)((item) => item.id); - }); + return with_next_cursor(limit, items)((item) => item.id); + }), +}); function profile_filter( profile_id: string, diff --git a/packages/@1/modules/notification/api/src/count_unread.ts b/packages/@1/modules/notification/api/src/count_unread.ts deleted file mode 100644 index 29157cc0f..000000000 --- a/packages/@1/modules/notification/api/src/count_unread.ts +++ /dev/null @@ -1,76 +0,0 @@ -// - -import { NotificationType } from "@1.infra/database"; -import { NotificationGroup } from "@1.modules/notification.domain"; -import { next_auth_procedure } from "@1.modules/trpc"; -import { P, match } from "ts-pattern"; -import { z } from "zod"; - -// - -const EXCHANGE_NOTIFICATIONS = [ - NotificationType.EXCHANGE_COMPLETED, - NotificationType.EXCHANGE_NEW_MESSAGE, - NotificationType.EXCHANGE_NEW_PARTICIPANT, -]; - -// - -export default next_auth_procedure - .input( - z.object({ - type: NotificationGroup.optional(), - }), - ) - .query(async ({ input: { type }, ctx: { prisma, payload } }) => { - const { id: owner_id } = payload.profile; - - const sub_count = await match(type) - .with(NotificationGroup.Enum.INBOX, async () => { - const data = await prisma.inboxMessageNotification.findMany({ - select: { message: { select: { thread_id: true } } }, - where: { - notification: { - owner_id, - read_at: null, - type: NotificationType.INBOX_NEW_MESSAGE, - }, - }, - }); - return new Set(data.map(({ message }) => message?.thread_id)); - }) - .with(NotificationGroup.Enum.EXCHANGE, async () => { - const data = await prisma.exchangeMessageNotification.findMany({ - select: { message: { select: { thread_id: true } } }, - where: { - notification: { - owner_id, - read_at: null, - type: { - in: EXCHANGE_NOTIFICATIONS, - }, - }, - }, - }); - return new Set(data.map(({ message }) => message?.thread_id)); - }) - .otherwise(() => Promise.resolve(null)); - - if (sub_count) return sub_count.size; - - const notification_type = match(type) - .with(NotificationGroup.Enum.EXCHANGE, () => ({ - type: { - in: EXCHANGE_NOTIFICATIONS, - }, - })) - .with(NotificationGroup.Enum.INBOX, () => ({ - type: NotificationType.INBOX_NEW_MESSAGE, - })) - .with(P.nullish, () => ({})) - .exhaustive(); - - return prisma.notification.count({ - where: { owner_id, read_at: null, ...notification_type }, - }); - }); diff --git a/packages/@1/modules/notification/api/src/count_unread/__snapshots__/count_unread.e2e.test.ts.snap b/packages/@1/modules/notification/api/src/count_unread/__snapshots__/count_unread.e2e.test.ts.snap new file mode 100644 index 000000000..850fb2b5d --- /dev/null +++ b/packages/@1/modules/notification/api/src/count_unread/__snapshots__/count_unread.e2e.test.ts.snap @@ -0,0 +1,7 @@ +// Bun Snapshot v1, https://goo.gl/fbAQLP + +exports[`return count of all unread notifications 1`] = `6`; + +exports[`return count of exchange notifications 1`] = `1`; + +exports[`return count of inbox notifications 1`] = `1`; diff --git a/packages/@1/modules/notification/api/src/count_unread/count_unread.e2e.test.ts b/packages/@1/modules/notification/api/src/count_unread/count_unread.e2e.test.ts new file mode 100644 index 000000000..3ee5933e7 --- /dev/null +++ b/packages/@1/modules/notification/api/src/count_unread/count_unread.e2e.test.ts @@ -0,0 +1,131 @@ +// + +import { + create_douglas_student, + create_greatings_message, + create_joedart_student, +} from "@1.infra/database/seeding"; +import prisma, { empty_database, migrate } from "@1.infra/database/testing"; +import { createCallerFactory } from "@1.modules/trpc"; +import { douglas_student_session } from "@1.modules/trpc/testing"; +import { afterEach, beforeAll, beforeEach, expect, test } from "bun:test"; +import api_router from "./count_unread"; + +// + +beforeAll(empty_database); +beforeAll(migrate); + +// + +test("return count of all unread notifications", async () => { + const caller = createCallerFactory(api_router); + const trpc = caller({ + auth: () => douglas_student_session, + prisma, + } as any); + const data = await trpc.count_unread({}); + expect(data).toMatchSnapshot(); +}); + +test("return count of exchange notifications", async () => { + const caller = createCallerFactory(api_router); + const trpc = caller({ + auth: () => douglas_student_session, + prisma, + } as any); + const data = await trpc.count_unread({ type: "EXCHANGE" }); + expect(data).toMatchSnapshot(); +}); + +test("return count of inbox notifications", async () => { + const caller = createCallerFactory(api_router); + const trpc = caller({ + auth: () => douglas_student_session, + prisma, + } as any); + const data = await trpc.count_unread({ type: "INBOX" }); + expect(data).toMatchSnapshot(); +}); + +// + +beforeEach(async function seed() { + await create_douglas_student(prisma); + await create_joedart_student(prisma); + await create_greatings_message( + prisma, + "douglas_profile_id", + "joedart_profile_id", + ); + + const { id: message_id } = await prisma.message.create({ + data: { + thread: { create: {} }, + author: { connect: { id: "douglas_profile_id" } }, + content: "World", + created_at: new Date(), + updated_at: new Date(), + }, + select: { id: true }, + }); + + await prisma.exchangeMessageNotification.create({ + data: { + message: { connect: { id: message_id } }, + notification: { + create: { + owner_id: "douglas_profile_id", + read_at: null, + type: "EXCHANGE_COMPLETED", + }, + }, + }, + }); + + await prisma.exchangeMessageNotification.create({ + data: { + message: { connect: { id: message_id } }, + notification: { + create: { + owner_id: "douglas_profile_id", + read_at: null, + type: "EXCHANGE_NEW_MESSAGE", + }, + }, + }, + }); + + await prisma.exchangeMessageNotification.create({ + data: { + message: { connect: { id: message_id } }, + notification: { + create: { + owner_id: "douglas_profile_id", + read_at: null, + type: "EXCHANGE_NEW_PARTICIPANT", + }, + }, + }, + }); + + await prisma.notification.createMany({ + data: [ + { + owner_id: "douglas_profile_id", + read_at: null, + type: "FORUM_NEW_AWNSER", + }, + { + owner_id: "douglas_profile_id", + read_at: null, + type: "PROFILE_ADDED", + }, + ], + }); +}); + +afterEach(async function empty_delete_entries() { + await prisma.thread.deleteMany(); + await prisma.user.deleteMany(); +}); diff --git a/packages/@1/modules/notification/api/src/count_unread/count_unread.ts b/packages/@1/modules/notification/api/src/count_unread/count_unread.ts new file mode 100644 index 000000000..1878ccd94 --- /dev/null +++ b/packages/@1/modules/notification/api/src/count_unread/count_unread.ts @@ -0,0 +1,78 @@ +// + +import { NotificationType } from "@1.infra/database"; +import { NotificationGroup } from "@1.modules/notification.domain"; +import { router, session_procedure } from "@1.modules/trpc"; +import { P, match } from "ts-pattern"; +import { z } from "zod"; + +// + +const EXCHANGE_NOTIFICATIONS = [ + NotificationType.EXCHANGE_COMPLETED, + NotificationType.EXCHANGE_NEW_MESSAGE, + NotificationType.EXCHANGE_NEW_PARTICIPANT, +]; + +// + +export default router({ + count_unread: session_procedure + .input( + z.object({ + type: NotificationGroup.optional(), + }), + ) + .query(async ({ input: { type }, ctx: { prisma, session } }) => { + const { id: owner_id } = session.profile; + + const sub_count = await match(type) + .with(NotificationGroup.Enum.INBOX, async () => { + const data = await prisma.inboxMessageNotification.findMany({ + select: { message: { select: { thread_id: true } } }, + where: { + notification: { + owner_id, + read_at: null, + type: NotificationType.INBOX_NEW_MESSAGE, + }, + }, + }); + return new Set(data.map(({ message }) => message?.thread_id)); + }) + .with(NotificationGroup.Enum.EXCHANGE, async () => { + const data = await prisma.exchangeMessageNotification.findMany({ + select: { message: { select: { thread_id: true } } }, + where: { + notification: { + owner_id, + read_at: null, + type: { + in: EXCHANGE_NOTIFICATIONS, + }, + }, + }, + }); + return new Set(data.map(({ message }) => message?.thread_id)); + }) + .otherwise(() => Promise.resolve(null)); + + if (sub_count) return sub_count.size; + + const notification_type = match(type) + .with(NotificationGroup.Enum.EXCHANGE, () => ({ + type: { + in: EXCHANGE_NOTIFICATIONS, + }, + })) + .with(NotificationGroup.Enum.INBOX, () => ({ + type: NotificationType.INBOX_NEW_MESSAGE, + })) + .with(P.nullish, () => ({})) + .exhaustive(); + + return prisma.notification.count({ + where: { owner_id, read_at: null, ...notification_type }, + }); + }), +}); diff --git a/packages/@1/modules/notification/api/src/count_unread/index.ts b/packages/@1/modules/notification/api/src/count_unread/index.ts new file mode 100644 index 000000000..436aa930e --- /dev/null +++ b/packages/@1/modules/notification/api/src/count_unread/index.ts @@ -0,0 +1,3 @@ +// + +export { default as count_unread_api_router } from "./count_unread"; diff --git a/packages/@1/modules/notification/api/src/find.ts b/packages/@1/modules/notification/api/src/find.ts deleted file mode 100644 index 525b362d2..000000000 --- a/packages/@1/modules/notification/api/src/find.ts +++ /dev/null @@ -1,93 +0,0 @@ -// - -import type { Prisma } from "@1.infra/database"; -import { next_auth_procedure } from "@1.modules/trpc"; -import { z } from "zod"; - -// - -export default next_auth_procedure - .input( - z.object({ - cursor: z.string().optional(), - limit: z.number().min(1).max(10).default(10), - }), - ) - .query(async ({ input, ctx: { prisma, payload } }) => { - const { cursor, limit } = input; - const { id: owner_id } = payload.profile; - const message_select: Prisma.MessageSelect = { - author: { select: { name: true, id: true, image: true } }, - thread_id: true, - }; - - const items = await prisma.notification.findMany({ - ...(cursor ? { cursor: { id: cursor } } : {}), - orderBy: { created_at: "desc" }, - take: limit + 1, - where: { owner_id }, - include: { - inbox_message: { - select: { - message: { - select: message_select, - }, - }, - }, - exchange_message: { - select: { - exchange: { - select: { - id: true, - owner: { - select: { - profile: { select: { id: true, name: true, image: true } }, - }, - }, - title: true, - }, - }, - message: { - select: message_select, - }, - }, - }, - forum_message: { - select: { - answer: { - select: { - owner: { - select: { - profile_id: true, - profile: { select: { name: true, image: true } }, - }, - }, - parent_id: true, - parent: { select: { id: true, title: true } }, - }, - }, - answer_id: true, - }, - }, - profile_added: { - select: { - profile: { - select: { - name: true, - id: true, - image: true, - }, - }, - }, - }, - }, - }); - - let prevCursor: typeof cursor | undefined = undefined; - if (items.length > limit) { - const nextItem = items.pop()!; - prevCursor = nextItem.id; - } - - return { data: items, prevCursor }; - }); diff --git a/packages/@1/modules/notification/api/src/find/__snapshots__/find.e2e.test.ts.snap b/packages/@1/modules/notification/api/src/find/__snapshots__/find.e2e.test.ts.snap new file mode 100644 index 000000000..d09c0a53c --- /dev/null +++ b/packages/@1/modules/notification/api/src/find/__snapshots__/find.e2e.test.ts.snap @@ -0,0 +1,29 @@ +// Bun Snapshot v1, https://goo.gl/fbAQLP + +exports[`should return latest notifications 1`] = ` +{ + "data": [ + { + "created_at": 2011-11-11T00:00:00.000Z, + "exchange_message": null, + "forum_message": null, + "id": "greatings_notification_id", + "inbox_message": { + "message": { + "author": { + "id": "joedart_profile_id", + "image": "https://picsum.photos/200/300", + "name": "Joe Dart", + }, + "thread_id": "greatings_thread_id", + }, + }, + "owner_id": "douglas_profile_id", + "profile_added": null, + "read_at": null, + "type": "INBOX_NEW_MESSAGE", + }, + ], + "prevCursor": undefined, +} +`; diff --git a/packages/@1/modules/notification/api/src/find/find.e2e.test.ts b/packages/@1/modules/notification/api/src/find/find.e2e.test.ts new file mode 100644 index 000000000..4e1a465d4 --- /dev/null +++ b/packages/@1/modules/notification/api/src/find/find.e2e.test.ts @@ -0,0 +1,57 @@ +// + +import { + create_douglas_student, + create_greatings_message, + create_joedart_student, +} from "@1.infra/database/seeding"; +import prisma, { empty_database, migrate } from "@1.infra/database/testing"; +import { createCallerFactory } from "@1.modules/trpc"; +import { douglas_student_session } from "@1.modules/trpc/testing"; +import { + afterEach, + beforeAll, + beforeEach, + expect, + setSystemTime, + test, +} from "bun:test"; +import find_api_router from "./find"; + +// + +beforeAll(empty_database); +beforeAll(migrate); +beforeAll(() => { + setSystemTime(new Date("2011-11-11")); +}); + +// + +test("should return latest notifications", async () => { + const caller = createCallerFactory(find_api_router); + const trpc = caller({ + auth: () => douglas_student_session, + prisma, + } as any); + const exchange = await trpc.find({}); + expect(exchange).toMatchSnapshot(); +}); + +// + +beforeEach(async function seed() { + await create_douglas_student(prisma); + await create_joedart_student(prisma); + await create_greatings_message( + prisma, + "douglas_profile_id", + "joedart_profile_id", + ); +}); + +afterEach(async function empty_delete_entries() { + await prisma.category.deleteMany({}); + await prisma.notification.deleteMany({}); + await prisma.user.deleteMany({}); +}); diff --git a/packages/@1/modules/notification/api/src/find/find.ts b/packages/@1/modules/notification/api/src/find/find.ts new file mode 100644 index 000000000..4ed1dc09e --- /dev/null +++ b/packages/@1/modules/notification/api/src/find/find.ts @@ -0,0 +1,81 @@ +// + +import type { Prisma } from "@1.infra/database"; +import { + router, + session_procedure, + with_previous_cursor, +} from "@1.modules/trpc"; +import { z } from "zod"; + +// + +export default router({ + find: session_procedure + .input( + z.object({ + cursor: z.string().optional(), + limit: z.number().min(1).max(10).default(10), + }), + ) + .query(async ({ input, ctx: { prisma, session } }) => { + const { cursor, limit } = input; + const { id: owner_id } = session.profile; + const message_select: Prisma.MessageSelect = { + author: { select: { name: true, id: true, image: true } }, + thread_id: true, + }; + + const items = await prisma.notification.findMany({ + ...(cursor ? { cursor: { id: cursor } } : {}), + orderBy: { created_at: "desc" }, + take: limit + 1, + where: { owner_id }, + include: { + inbox_message: { select: { message: { select: message_select } } }, + exchange_message: { + select: { + exchange: { + select: { + id: true, + owner: { + select: { + profile: { + select: { id: true, name: true, image: true }, + }, + }, + }, + title: true, + }, + }, + message: { select: message_select }, + }, + }, + forum_message: { + select: { + answer: { + select: { + owner: { + select: { + profile_id: true, + profile: { select: { name: true, image: true } }, + }, + }, + parent_id: true, + parent: { select: { id: true, title: true } }, + }, + }, + answer_id: true, + }, + }, + profile_added: { + select: { + profile: { select: { name: true, id: true, image: true } }, + }, + }, + }, + }); + + return with_previous_cursor(limit, items)((item) => item.id); + }), +}); diff --git a/packages/@1/modules/notification/api/src/find/index.ts b/packages/@1/modules/notification/api/src/find/index.ts new file mode 100644 index 000000000..554151cdf --- /dev/null +++ b/packages/@1/modules/notification/api/src/find/index.ts @@ -0,0 +1,3 @@ +// + +export { default as find_api_router } from "./find"; diff --git a/packages/@1/modules/notification/api/src/index.ts b/packages/@1/modules/notification/api/src/index.ts index bb9ab9769..8421cfe50 100644 --- a/packages/@1/modules/notification/api/src/index.ts +++ b/packages/@1/modules/notification/api/src/index.ts @@ -1,16 +1,18 @@ // -import { router } from "@1.modules/trpc"; -import count_unread from "./count_unread"; -import find from "./find"; +import { mergeRouters, router } from "@1.modules/trpc"; +import { count_unread_api_router } from "./count_unread"; +import { find_api_router } from "./find"; import mark_as_read from "./mark_as_read"; // const notification_api_router = router({ - count_unread: count_unread, - find: find, mark_as_read: mark_as_read, }); -export default notification_api_router; +export default mergeRouters( + count_unread_api_router, + find_api_router, + notification_api_router, +); diff --git a/packages/@1/modules/trpc/src/testing/index.ts b/packages/@1/modules/trpc/src/testing/index.ts index 39e770a09..467a0d58c 100644 --- a/packages/@1/modules/trpc/src/testing/index.ts +++ b/packages/@1/modules/trpc/src/testing/index.ts @@ -1,11 +1,24 @@ // +import type { Session } from "@1.modules/auth.next"; import { create_nextauth_header } from "@1.modules/auth.next/jwt"; // export const NEXTAUTH_SECRET = "🔑"; +export const douglas_student_session: Session = { + expires: "2022-12-31T23:59:59.999Z", + user: {}, + header: { NEXTAUTH_TOKEN: "🔑" }, + profile: { + id: "douglas_profile_id", + image: "https://picsum.photos/222/333", + name: "Douglas", + role: "STUDENT", + }, +}; + export const douglas_golden_nextauth_header = await create_nextauth_header({ secret: "🔑", token: { diff --git a/serkels.code-workspace b/serkels.code-workspace index 4084b6504..47f4fec35 100644 --- a/serkels.code-workspace +++ b/serkels.code-workspace @@ -297,6 +297,17 @@ "problemMatcher": ["$tsc-watch"], "runOptions": { "instanceLimit": 1 }, }, + { + "label": "🧪 Update Test Snapshots : Current file", + "command": "bun test --update-snapshots ${fileDirname}/${fileBasename}", + "type": "shell", + "group": "build", + "options": { + "cwd": "${workspaceFolder:root}", + }, + "problemMatcher": ["$tsc-watch"], + "runOptions": { "instanceLimit": 1 }, + }, { "label": "🧪 Watch Test", "command": "bun test --watch", From af575bb953a75a04a0ba74480771fc55d574088b Mon Sep 17 00:00:00 2001 From: Douglas DUTEIL Date: Mon, 18 Nov 2024 02:55:31 +0100 Subject: [PATCH 2/3] SAVE --- .github/workflows/e2e.yaml | 1 + .../support/step_definitions/general.ts | 4 + .../exchanges/create_exchange.feature | 46 ++++ .../exchanges/studient_filters.feature | 12 + apps/e2e/features/notification/page.feature | 10 + apps/e2e/features/partner/welcome.feature | 12 + apps/e2e/features/studient/welcome.feature | 12 + .../features/studient_exchanges/inbox.feature | 24 ++ apps/www/app/(auth)/signup/student/page.tsx | 5 +- .../[code]/(private)/bookmarks/layout.tsx | 8 +- .../bookmarks/opportunities/page.tsx | 4 +- .../[exchange_id]/edit/page.client.tsx | 5 +- .../exchanges/[exchange_id]/edit/page.tsx | 7 +- .../[thread_id]/_client/Conversation_Form.tsx | 2 +- .../[code]/(private)/exchanges/layout.tsx | 2 +- .../[code]/(private)/exchanges/mine/page.tsx | 2 +- .../[thread_id]/_client/Conversation_Form.tsx | 2 +- .../(private)/inbox/[thread_id]/page.tsx | 2 +- .../inbox/write_to/[profile_id]/page.tsx | 6 +- .../_client/Infinite_Contacts_List.tsx | 2 +- .../[code]/(private)/inbox/write_to/page.tsx | 2 +- .../[code]/(private)/notifications/layout.tsx | 10 + .../[code]/(private)/notifications/page.tsx | 5 +- .../[code]/(private)/opportunities/layout.tsx | 2 +- .../parameters/_client/Avatar_Editor.tsx | 2 +- .../parameters/_client/Profile_Editor.tsx | 6 +- .../door/[code]/(private)/parameters/page.tsx | 14 +- .../[code]/(private)/parameters/upload.tsx | 7 +- .../[code]/(private)/welcome/page.client.tsx | 19 -- .../door/[code]/(private)/welcome/page.tsx | 23 +- .../door/[code]/(public)/(about)/page.tsx | 6 +- .../[code]/(public)/@header/AddedByCount.tsx | 2 +- .../[code]/(public)/@header/CircleCount.tsx | 2 +- .../door/[code]/(public)/@header/default.tsx | 8 +- .../(public)/@navbar/_client/AddContact.tsx | 22 +- .../door/[code]/(public)/@navbar/default.tsx | 2 +- .../_client/Infinite_Contacts_List.tsx | 2 +- .../door/[code]/(public)/contacts/page.tsx | 2 +- .../(public)/following/_client/List.tsx | 2 +- .../door/[code]/(public)/following/page.tsx | 2 +- .../door/[code]/(public)/history/page.tsx | 2 +- .../[code]/(public)/opportunities/page.tsx | 2 +- .../door/[code]/(public)/proposals/layout.tsx | 8 + .../door/[code]/(public)/proposals/page.tsx | 11 +- .../(main)/door/[code]/@navbar/default.tsx | 6 +- .../app/(main)/door/[code]/report/action.ts | 2 +- .../(main)/exchanges/[exchange_id]/Card.tsx | 4 +- .../(main)/exchanges/[exchange_id]/layout.tsx | 5 +- .../(main)/exchanges/[exchange_id]/page.tsx | 4 +- apps/www/app/(main)/exchanges/layout.tsx | 11 +- apps/www/app/(main)/exchanges/page.tsx | 15 +- apps/www/app/(main)/forum/_client/List.tsx | 2 +- apps/www/app/(main)/forum/layout.tsx | 12 +- apps/www/app/(main)/layout.tsx | 4 +- .../opportunities/[slug]/@see_also/page.tsx | 7 +- .../(main)/opportunities/[slug]/delete.tsx | 6 +- .../(main)/opportunities/[slug]/layout.tsx | 8 +- .../app/(main)/opportunities/_client/List.tsx | 4 +- apps/www/app/(main)/opportunities/layout.tsx | 11 +- apps/www/app/(main)/opportunities/page.tsx | 5 +- apps/www/components/Share_Button.tsx | 1 + apps/www/components/avatar/index.tsx | 11 +- apps/www/components/button/AddToMyCircles.tsx | 11 +- apps/www/components/button/BlockProfile.tsx | 7 +- .../navbar/UserBar.client.tsx} | 7 +- .../navbar/UserBar.tsx} | 12 +- apps/www/components/navbar/aside_navbar.tsx | 9 +- .../BlockedProfile_Placeholder.tsx | 2 +- apps/www/components/shell/RootProviders.tsx | 4 +- apps/www/widgets/exchanges/card/actions.tsx | 4 +- apps/www/widgets/exchanges/card/bookmark.tsx | 8 +- apps/www/widgets/exchanges/card/index.tsx | 8 +- apps/www/widgets/exchanges/card/share.tsx | 2 +- apps/www/widgets/exchanges/list/List.tsx | 6 +- .../widgets/inbox/BlockedProfileWarning.tsx | 2 +- apps/www/widgets/opportunities/card/index.tsx | 6 +- apps/www/widgets/opportunities/list/index.tsx | 18 +- .../database/seeding/studient/douglas.ts | 2 + .../database/seeding/studient/joedart.ts | 2 + .../infra/database/seeding/studient/johan.ts | 4 + packages/@1/infra/database/testing/index.ts | 1 + packages/@1/infra/trpc/src/index.ts | 2 + packages/@1/modules/auth/api/src/index.ts | 4 +- .../@1/modules/auth/api/src/verify/index.ts | 16 +- .../auth/api/src/verify/verify.e2e.test.ts | 2 +- .../@1/modules/auth/api/src/verify/verify.ts | 17 ++ packages/@1/modules/bookmark/api/package.json | 1 + .../bookmark/api/src/check/check.e2e.test.ts | 66 ++++++ .../modules/bookmark/api/src/check/check.ts | 32 +++ .../modules/bookmark/api/src/check/index.ts | 3 + packages/@1/modules/bookmark/api/src/index.ts | 48 +--- .../@1/modules/bookmark/api/src/procedure.ts | 11 + .../@1/modules/bookmark/api/tsconfig.json | 2 +- .../__snapshots__/delete.e2e.test.ts.snap | 39 ++++ .../api/src/me/delete/delete.e2e.test.ts | 42 ++++ .../exchange/api/src/me/delete/delete.ts | 17 ++ .../exchange/api/src/me/delete/index.ts | 3 + .../exchange/api/src/me/find.e2e.test.ts | 4 +- .../@1/modules/exchange/api/src/me/index.ts | 32 +-- .../exchange/api/src/public/by_id.e2e.test.ts | 8 +- .../exchange/api/src/public/find.e2e.test.ts | 24 +- packages/@1/modules/forum/api/src/answers.ts | 76 ++----- .../__snapshots__/create.e2e.test.ts.snap | 13 ++ .../api/src/answers/create/create.e2e.test.ts | 66 ++++++ .../forum/api/src/answers/create/create.ts | 54 +++++ .../forum/api/src/answers/create/index.ts | 3 + .../__snapshots__/delete.e2e.test.ts.snap | 12 + .../api/src/answers/delete/delete.e2e.test.ts | 70 ++++++ .../forum/api/src/answers/delete/delete.ts | 27 +++ .../forum/api/src/answers/delete/index.ts | 3 + .../forum/api/src/answers/procedure.ts | 10 + packages/@1/modules/forum/api/src/question.ts | 40 +--- .../__snapshots__/create.e2e.test.ts.snap | 13 ++ .../src/question/create/create.e2e.test.ts | 54 +++++ .../forum/api/src/question/create/create.ts | 23 ++ .../forum/api/src/question/create/index.ts | 3 + .../__snapshots__/delete.e2e.test.ts.snap | 13 ++ .../src/question/delete/delete.e2e.test.ts | 60 +++++ .../forum/api/src/question/delete/delete.ts | 16 ++ .../forum/api/src/question/delete/index.ts | 3 + .../find/__snapshots__/find.e2e.test.ts.snap | 209 ++++++++++++++++++ .../{index.e2e.test.ts => find.e2e.test.ts} | 118 ++++------ .../forum/api/src/question/find/find.ts | 142 ++++++++++++ .../forum/api/src/question/find/index.ts | 135 +---------- packages/@1/modules/forum/domain/src/index.ts | 9 +- .../@1/modules/opportunity/ui/src/Card.tsx | 1 + .../__snapshots__/find_by_id.e2e.test.ts.snap | 17 ++ .../api/src/find_by_id/find_by_id.e2e.test.ts | 73 ++++++ .../profile/api/src/find_by_id/find_by_id.ts | 29 +++ .../profile/api/src/find_by_id/index.ts | 3 + packages/@1/modules/profile/api/src/index.ts | 63 +----- packages/@1/modules/profile/api/src/legacy.ts | 63 ++++++ packages/@1/modules/trpc/src/index.ts | 1 + packages/@1/ui/react/src/avatar/atom.ts | 19 ++ packages/@1/ui/react/src/avatar/index.tsx | 3 + pnpm-lock.yaml | 3 + 136 files changed, 1750 insertions(+), 634 deletions(-) create mode 100644 apps/e2e/features/exchanges/create_exchange.feature create mode 100644 apps/e2e/features/exchanges/studient_filters.feature create mode 100644 apps/e2e/features/notification/page.feature create mode 100644 apps/e2e/features/partner/welcome.feature create mode 100644 apps/e2e/features/studient/welcome.feature create mode 100644 apps/e2e/features/studient_exchanges/inbox.feature create mode 100644 apps/www/app/(main)/door/[code]/(private)/notifications/layout.tsx delete mode 100644 apps/www/app/(main)/door/[code]/(private)/welcome/page.client.tsx create mode 100644 apps/www/app/(main)/door/[code]/(public)/proposals/layout.tsx rename apps/www/{app/(main)/navbar.client.tsx => components/navbar/UserBar.client.tsx} (94%) rename apps/www/{app/(main)/navbar.tsx => components/navbar/UserBar.tsx} (93%) create mode 100644 packages/@1/modules/auth/api/src/verify/verify.ts create mode 100644 packages/@1/modules/bookmark/api/src/check/check.e2e.test.ts create mode 100644 packages/@1/modules/bookmark/api/src/check/check.ts create mode 100644 packages/@1/modules/bookmark/api/src/check/index.ts create mode 100644 packages/@1/modules/bookmark/api/src/procedure.ts create mode 100644 packages/@1/modules/exchange/api/src/me/delete/__snapshots__/delete.e2e.test.ts.snap create mode 100644 packages/@1/modules/exchange/api/src/me/delete/delete.e2e.test.ts create mode 100644 packages/@1/modules/exchange/api/src/me/delete/delete.ts create mode 100644 packages/@1/modules/exchange/api/src/me/delete/index.ts create mode 100644 packages/@1/modules/forum/api/src/answers/create/__snapshots__/create.e2e.test.ts.snap create mode 100644 packages/@1/modules/forum/api/src/answers/create/create.e2e.test.ts create mode 100644 packages/@1/modules/forum/api/src/answers/create/create.ts create mode 100644 packages/@1/modules/forum/api/src/answers/create/index.ts create mode 100644 packages/@1/modules/forum/api/src/answers/delete/__snapshots__/delete.e2e.test.ts.snap create mode 100644 packages/@1/modules/forum/api/src/answers/delete/delete.e2e.test.ts create mode 100644 packages/@1/modules/forum/api/src/answers/delete/delete.ts create mode 100644 packages/@1/modules/forum/api/src/answers/delete/index.ts create mode 100644 packages/@1/modules/forum/api/src/answers/procedure.ts create mode 100644 packages/@1/modules/forum/api/src/question/create/__snapshots__/create.e2e.test.ts.snap create mode 100644 packages/@1/modules/forum/api/src/question/create/create.e2e.test.ts create mode 100644 packages/@1/modules/forum/api/src/question/create/create.ts create mode 100644 packages/@1/modules/forum/api/src/question/create/index.ts create mode 100644 packages/@1/modules/forum/api/src/question/delete/__snapshots__/delete.e2e.test.ts.snap create mode 100644 packages/@1/modules/forum/api/src/question/delete/delete.e2e.test.ts create mode 100644 packages/@1/modules/forum/api/src/question/delete/delete.ts create mode 100644 packages/@1/modules/forum/api/src/question/delete/index.ts create mode 100644 packages/@1/modules/forum/api/src/question/find/__snapshots__/find.e2e.test.ts.snap rename packages/@1/modules/forum/api/src/question/find/{index.e2e.test.ts => find.e2e.test.ts} (57%) create mode 100644 packages/@1/modules/forum/api/src/question/find/find.ts create mode 100644 packages/@1/modules/profile/api/src/find_by_id/__snapshots__/find_by_id.e2e.test.ts.snap create mode 100644 packages/@1/modules/profile/api/src/find_by_id/find_by_id.e2e.test.ts create mode 100644 packages/@1/modules/profile/api/src/find_by_id/find_by_id.ts create mode 100644 packages/@1/modules/profile/api/src/find_by_id/index.ts create mode 100644 packages/@1/modules/profile/api/src/legacy.ts diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 9e0c4f081..47cf25f48 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -86,6 +86,7 @@ jobs: - forum - legal - moderation + - notification - opportunity - partner - status diff --git a/apps/e2e/cypress/support/step_definitions/general.ts b/apps/e2e/cypress/support/step_definitions/general.ts index a958dc64c..e96559e30 100644 --- a/apps/e2e/cypress/support/step_definitions/general.ts +++ b/apps/e2e/cypress/support/step_definitions/general.ts @@ -18,6 +18,10 @@ Then("je vois {string}", function (text: string) { cy.contains(text); }); +Then("je ne vois pas {string}", function (text: string) { + cy.contains(text).should("not.exist"); +}); + Then("je vois la légende {string}", function (text: string) { cy.get(`[aria-label*="${text}"]`); }); diff --git a/apps/e2e/features/exchanges/create_exchange.feature b/apps/e2e/features/exchanges/create_exchange.feature new file mode 100644 index 000000000..6aa942d80 --- /dev/null +++ b/apps/e2e/features/exchanges/create_exchange.feature @@ -0,0 +1,46 @@ +#language: fr +Fonctionnalité: Posez une question + + Scénario: Les visiteurs ne peuvent pas créer un échange + Soit une base de données nourrie au grain + * je navigue sur la page + Quand je clique sur "Échanges" + * je vois dans le titre "Exchange :: Serkels" + + Alors je ne vois pas "Créer un échange" + + Scénario: Douglas crée l'échange "The Creator" + Soit une base de données nourrie au grain + * je navigue sur la page + * je me connecte en tant que "douglas@yopmail.com" + * je clique sur "Échanges" + * je vois dans le titre "Exchange :: Serkels" + Quand je clique sur "Créer un nouvel échange" + * je vois dans le titre "New :: Exchanges :: Serkels" + + * je clique sur "Je propose" + * je clique sur "Sur place" + + * je clique sur "Ville" + * je tape "Nice" + + * je clique sur "Dans quelle categorie ?" + * je choisis l'option "Autres" + + * je clique sur "Titre" + * je tape "The Creator" + + * je clique sur "Description" + * je tape "*The Creator* is a good film and you should watch it ;)" + + * je clique sur "Sans échange" + + Quand je clique sur "Publier" + Alors je vois "The Creator" + * je vois "The Creator is a good film" + * je vois "Proposition" + * je vois "Nice" + * je vois "Autres" + * je vois "Sans échange" + * je vois "Date limite : flexible" + * je vois "Voir mes échanges" diff --git a/apps/e2e/features/exchanges/studient_filters.feature b/apps/e2e/features/exchanges/studient_filters.feature new file mode 100644 index 000000000..6b6372a67 --- /dev/null +++ b/apps/e2e/features/exchanges/studient_filters.feature @@ -0,0 +1,12 @@ +#language: fr +Fonctionnalité: Posez une question + + Scénario: Poser une question sur le forum + Soit une base de données nourrie au grain + * je navigue sur la page + * je me connecte en tant que "douglas@yopmail.com" + * je clique sur "Échanges" + * je vois dans le titre "Exchange :: Serkels" + + Quand je clique sur "Mes cercles" + Alors je vois "P'tit pause café avec l'ami Jackie" diff --git a/apps/e2e/features/notification/page.feature b/apps/e2e/features/notification/page.feature new file mode 100644 index 000000000..c9f277abc --- /dev/null +++ b/apps/e2e/features/notification/page.feature @@ -0,0 +1,10 @@ +#language: fr +Fonctionnalité: Page de notifications + Scénario: Voir la page de notifications + Soit une base de données nourrie au grain + Etant donné que je navigue sur la page + * je me connecte en tant que "douglas@yopmail.com" + Quand je visite la page "/@~/notifications" + Alors je vois dans le titre "Notifications :: Serkels" + * je vois "Notifications" + * je vois "vous a ajouté dans son cercle." diff --git a/apps/e2e/features/partner/welcome.feature b/apps/e2e/features/partner/welcome.feature new file mode 100644 index 000000000..faae8a80d --- /dev/null +++ b/apps/e2e/features/partner/welcome.feature @@ -0,0 +1,12 @@ +#language: fr +Fonctionnalité: Consulter les échanges proposés d'un étudiant + Contexte: + Soit une base de données nourrie au grain + + Scénario: La biographie de douglas@yopmail.com + Etant donné que je navigue sur la page + * je me connecte en tant que "onedoesuniversity@yopmail.com" + * je visite la page "/@~/welcome" + Alors je vois dans le titre "Welcome :: Serkels" + * je vois "Welcome" + * je vois "One Does University" diff --git a/apps/e2e/features/studient/welcome.feature b/apps/e2e/features/studient/welcome.feature new file mode 100644 index 000000000..d6e1a2db8 --- /dev/null +++ b/apps/e2e/features/studient/welcome.feature @@ -0,0 +1,12 @@ +#language: fr +Fonctionnalité: Consulter les échanges proposés d'un étudiant + Contexte: + Soit une base de données nourrie au grain + + Scénario: La biographie de douglas@yopmail.com + Etant donné que je navigue sur la page + * je me connecte en tant que "douglas@yopmail.com" + * je visite la page "/@~/welcome" + Alors je vois dans le titre "Welcome :: Serkels" + * je vois "Welcome" + * je vois "Douglas" diff --git a/apps/e2e/features/studient_exchanges/inbox.feature b/apps/e2e/features/studient_exchanges/inbox.feature new file mode 100644 index 000000000..9a08f361a --- /dev/null +++ b/apps/e2e/features/studient_exchanges/inbox.feature @@ -0,0 +1,24 @@ +#language: fr +Fonctionnalité: Envoyer un message a Jackie Smith + + Contexte: + Soit une base de données nourrie au grain + + Scénario: Douglas envoie un message à Jackie Smith + Etant donné que je navigue sur la page + * je me connecte en tant que "douglas@yopmail.com" + * je visite la page "/@~" + * je vois dans le titre "About :: Serkels" + * je clique sur "Messages privés" + * je vois dans le titre "Inbox :: Serkels" + + * je clique sur "Écrire" + * je vois dans le titre "Write to :: Inbox :: Serkels" + + Quand je clique sur "Jackie Smith" + + Alors je vois dans le titre "Jackie Smith :: Inbox :: Serkels" + * je tape "Hey Jackie, tu connais Hiatus Kaiyote ?" + * je clique sur la légende "Send" + * je vois "Hey Jackie, tu connais Hiatus Kaiyote ?" + * je vois dans le titre "Jackie Smith :: Inbox :: Serkels" diff --git a/apps/www/app/(auth)/signup/student/page.tsx b/apps/www/app/(auth)/signup/student/page.tsx index dd43dbaa5..5bbafed62 100644 --- a/apps/www/app/(auth)/signup/student/page.tsx +++ b/apps/www/app/(auth)/signup/student/page.tsx @@ -1,5 +1,6 @@ // +import { TrpcRootProvider } from ":trpc/root"; import { TRPC_SSR } from ":trpc/server"; import Form from ":widgets/auth/SignUpForm"; import { auth } from "@1.modules/auth.next"; @@ -37,7 +38,9 @@ async function Page() { return (
- + + +
); } diff --git a/apps/www/app/(main)/door/[code]/(private)/bookmarks/layout.tsx b/apps/www/app/(main)/door/[code]/(private)/bookmarks/layout.tsx index 0f9f09c60..3fbb6b123 100644 --- a/apps/www/app/(main)/door/[code]/(private)/bookmarks/layout.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/bookmarks/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata, ResolvingMetadata } from "next"; import type { PropsWithChildren } from "react"; +import { TrpcRootProvider } from ":trpc/root"; // @@ -15,6 +16,11 @@ export async function generateMetadata( } // + export default function Layout({ children }: PropsWithChildren) { - return
{children}
; + return ( + +
{children}
+
+ ); } diff --git a/apps/www/app/(main)/door/[code]/(private)/bookmarks/opportunities/page.tsx b/apps/www/app/(main)/door/[code]/(private)/bookmarks/opportunities/page.tsx index 82fab0c32..e86b46d65 100644 --- a/apps/www/app/(main)/door/[code]/(private)/bookmarks/opportunities/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/bookmarks/opportunities/page.tsx @@ -1,7 +1,7 @@ // -import { TRPC_SSR } from ":trpc/server"; import { Card } from ":widgets/opportunities/card"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; import type { Metadata, ResolvingMetadata } from "next"; // @@ -18,7 +18,7 @@ export async function generateMetadata( // export default async function Page() { const { data: opportunities } = - await TRPC_SSR.bookmarks.opportunities.find.fetch(); + await trpc_server.bookmarks.opportunities.find.fetch(); if (opportunities.length === 0) return ( diff --git a/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.client.tsx b/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.client.tsx index 25f9842b6..c16760f48 100644 --- a/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.client.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.client.tsx @@ -1,6 +1,7 @@ "use client"; import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import type { Category } from "@1.modules/category.domain"; import { type Exchange_Flat_Schema } from "@1.modules/exchange.domain"; import { @@ -21,8 +22,8 @@ export function Mutate_Exchange_Island({ }: { exchange_id: string; }) { - const { data: exchange } = TRPC_React.exchanges.by_id.useQuery(exchange_id); - const { data: categories } = TRPC_React.category.exchange.useQuery(); + const { data: exchange } = trpc_client.exchanges.by_id.useQuery(exchange_id); + const { data: categories } = trpc_client.category.exchange.useQuery(); if (!exchange) return null; if (!categories) return null; return ; diff --git a/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.tsx b/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.tsx index 2be46764a..18513093a 100644 --- a/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/exchanges/[exchange_id]/edit/page.tsx @@ -1,9 +1,10 @@ // import type { Params } from ":pipes/exchange_by_id"; -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; import type { Metadata, ResolvingMetadata } from "next"; import { Mutate_Exchange_Island } from "./page.client"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; // @@ -23,8 +24,8 @@ export default async function Page(props: { params: Promise }) { const params = await props.params; const { exchange_id } = params; - await TRPC_SSR.exchanges.by_id.prefetch(exchange_id); - await TRPC_SSR.category.exchange.prefetch(); + await trpc_server.exchanges.by_id.prefetch(exchange_id); + await trpc_server.category.exchange.prefetch(); return ( diff --git a/apps/www/app/(main)/door/[code]/(private)/exchanges/inbox/[exchange_id]/[thread_id]/_client/Conversation_Form.tsx b/apps/www/app/(main)/door/[code]/(private)/exchanges/inbox/[exchange_id]/[thread_id]/_client/Conversation_Form.tsx index 3d2141e7e..e9652fa50 100644 --- a/apps/www/app/(main)/door/[code]/(private)/exchanges/inbox/[exchange_id]/[thread_id]/_client/Conversation_Form.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/exchanges/inbox/[exchange_id]/[thread_id]/_client/Conversation_Form.tsx @@ -25,7 +25,7 @@ export default function Conversation_Form({ const is_active = is_active_exchange(exchange); const send_message = TRPC_React.inbox.thread.send.useMutation(); const utils = TRPC_React.useUtils(); - const blacklist_item = TRPC_React.profile.me.blacklist.find.useQuery({ + const blacklist_item = TRPC_React.legacy_profile.me.blacklist.find.useQuery({ profile_id: recipient_id, }); const form = useForm({ diff --git a/apps/www/app/(main)/door/[code]/(private)/exchanges/layout.tsx b/apps/www/app/(main)/door/[code]/(private)/exchanges/layout.tsx index f7c3664b5..968296c0c 100644 --- a/apps/www/app/(main)/door/[code]/(private)/exchanges/layout.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/exchanges/layout.tsx @@ -34,7 +34,7 @@ export default async function Layout( return ; } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); if (profile.role !== PROFILE_ROLES.Enum.STUDENT) { redirect(`/@${params.code}`); } diff --git a/apps/www/app/(main)/door/[code]/(private)/exchanges/mine/page.tsx b/apps/www/app/(main)/door/[code]/(private)/exchanges/mine/page.tsx index 4fef1a7c5..55ce85e35 100644 --- a/apps/www/app/(main)/door/[code]/(private)/exchanges/mine/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/exchanges/mine/page.tsx @@ -27,7 +27,7 @@ export default async function Page(props: { params: Promise }) { notFound(); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); const exchanges = await TRPC_SSR.exchanges.me.publications.fetch({}); const { base, empty } = main(); diff --git a/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/_client/Conversation_Form.tsx b/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/_client/Conversation_Form.tsx index 99f7feb29..1499c91c8 100644 --- a/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/_client/Conversation_Form.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/_client/Conversation_Form.tsx @@ -16,7 +16,7 @@ export default function Conversation_Form({ recipient_id, }: Params & { recipient_id: string }) { const { mutateAsync } = TRPC_React.inbox.thread.send.useMutation(); - const blacklist_item = TRPC_React.profile.me.blacklist.find.useQuery({ + const blacklist_item = TRPC_React.legacy_profile.me.blacklist.find.useQuery({ profile_id: recipient_id, }); const is_blacklisted = blacklist_item.data?.profile.id === recipient_id; diff --git a/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/page.tsx b/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/page.tsx index 50c874958..33f8af7ab 100644 --- a/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/inbox/[thread_id]/page.tsx @@ -89,7 +89,7 @@ export default async function Page(props: { params: Promise }) { await TRPC_SSR.inbox.thread.messages.prefetchInfinite({ thread_id, }); - await TRPC_SSR.profile.me.blacklist.find.prefetch({ + await TRPC_SSR.legacy_profile.me.blacklist.find.prefetch({ profile_id: recipient.id, }); diff --git a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/[profile_id]/page.tsx b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/[profile_id]/page.tsx index 4b182bc29..f73d8a38b 100644 --- a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/[profile_id]/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/[profile_id]/page.tsx @@ -17,7 +17,9 @@ export async function generateMetadata( parent: ResolvingMetadata, ): Promise { const params = await props.params; - const [, profile] = await to(TRPC_SSR.profile.by_id.fetch(params.profile_id)); + const [, profile] = await to( + TRPC_SSR.legacy_profile.by_id.fetch(params.profile_id), + ); const { name } = profile ?? { name: "O_0" }; const title = `${name} :: ${(await parent).title?.absolute}`; @@ -35,7 +37,7 @@ export default async function Page(props: { params: Promise }) { const params = await props.params; const inbox = await TRPC_SSR.inbox.by_profile_id.fetch(params); if (inbox) return redirect(`/@~/inbox/${inbox.thread.id}`); - const profile = await TRPC_SSR.profile.by_id.fetch(params.profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(params.profile_id); return (
diff --git a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/_client/Infinite_Contacts_List.tsx b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/_client/Infinite_Contacts_List.tsx index 635ae63ab..e2197c688 100644 --- a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/_client/Infinite_Contacts_List.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/_client/Infinite_Contacts_List.tsx @@ -12,7 +12,7 @@ import { P, match } from "ts-pattern"; // export default function Infinite_Contacts_List() { - const info = TRPC_React.profile.me.contacts.useInfiniteQuery( + const info = TRPC_React.legacy_profile.me.contacts.useInfiniteQuery( {}, { getNextPageParam: ({ next_cursor }) => next_cursor }, ); diff --git a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/page.tsx b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/page.tsx index 8a55539d0..78142e378 100644 --- a/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/inbox/write_to/page.tsx @@ -25,7 +25,7 @@ export async function generateMetadata( // export default async function Page() { - await TRPC_SSR.profile.me.contacts.prefetchInfinite({}); + await TRPC_SSR.legacy_profile.me.contacts.prefetchInfinite({}); return ( diff --git a/apps/www/app/(main)/door/[code]/(private)/notifications/layout.tsx b/apps/www/app/(main)/door/[code]/(private)/notifications/layout.tsx new file mode 100644 index 000000000..3aa6292e0 --- /dev/null +++ b/apps/www/app/(main)/door/[code]/(private)/notifications/layout.tsx @@ -0,0 +1,10 @@ +// + +import { TrpcRootProvider } from ":trpc/root"; +import type { PropsWithChildren } from "react"; + +// + +export default function Layout({ children }: PropsWithChildren) { + return {children}; +} diff --git a/apps/www/app/(main)/door/[code]/(private)/notifications/page.tsx b/apps/www/app/(main)/door/[code]/(private)/notifications/page.tsx index 143c62257..e1db244b4 100644 --- a/apps/www/app/(main)/door/[code]/(private)/notifications/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/notifications/page.tsx @@ -1,8 +1,9 @@ // -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; import type { Metadata, ResolvingMetadata } from "next"; import { AsyncListInfinite } from "./List"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; // @@ -23,7 +24,7 @@ export async function generateMetadata( // export default async function Page() { - await TRPC_SSR.notification.find.prefetchInfinite({}); + await trpc_server.notification.find.prefetchInfinite({}); // return ( diff --git a/apps/www/app/(main)/door/[code]/(private)/opportunities/layout.tsx b/apps/www/app/(main)/door/[code]/(private)/opportunities/layout.tsx index bb4630719..974132d7d 100644 --- a/apps/www/app/(main)/door/[code]/(private)/opportunities/layout.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/opportunities/layout.tsx @@ -33,7 +33,7 @@ export default async function Layout( return notFound(); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); if (profile.role !== PROFILE_ROLES.Enum.PARTNER) { redirect(`/@${params.code}`); } diff --git a/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Avatar_Editor.tsx b/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Avatar_Editor.tsx index 355cc4378..a03a114ab 100644 --- a/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Avatar_Editor.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Avatar_Editor.tsx @@ -24,7 +24,7 @@ export default function Avatar_Editor({ profile }: { profile: Profile }) { defaultValues: { profile_id: profile.id, image_file: new File([], "") }, }); const update_image_to_gravatar = - TRPC_React.profile.me.update_image_to_gravatar.useMutation(); + TRPC_React.legacy_profile.me.update_image_to_gravatar.useMutation(); const [preview, set_preview] = useState(profile.image); const { update } = useSession(); const router = useRouter(); diff --git a/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Profile_Editor.tsx b/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Profile_Editor.tsx index f72b70632..cd578ddcc 100644 --- a/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Profile_Editor.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/parameters/_client/Profile_Editor.tsx @@ -24,10 +24,10 @@ export default function Profile_Editor({ const utils = TRPC_React.useUtils(); const router = useRouter(); - const query_profile = TRPC_React.profile.by_id.useQuery(profile_id, { + const query_profile = TRPC_React.legacy_profile.by_id.useQuery(profile_id, { select: ({ bio, name }) => ({ bio, name }), }); - const update_profile = TRPC_React.profile.me.update.useMutation(); + const update_profile = TRPC_React.legacy_profile.me.update.useMutation(); const profile = query_profile.data ?? initial; @@ -38,7 +38,7 @@ export default function Profile_Editor({ const data = await update_profile.mutateAsync({ ...values, }); - await utils.profile.by_id.invalidate(profile_id); + await utils.legacy_profile.by_id.invalidate(profile_id); await update(); formik.resetForm({ values: { ...data, email: values.email } }); router.refresh(); diff --git a/apps/www/app/(main)/door/[code]/(private)/parameters/page.tsx b/apps/www/app/(main)/door/[code]/(private)/parameters/page.tsx index ce3bcb74d..d982c3e60 100644 --- a/apps/www/app/(main)/door/[code]/(private)/parameters/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/parameters/page.tsx @@ -1,7 +1,7 @@ // import { code_to_profile_id, type CodeParms } from ":pipes/code"; -import { TRPC_SSR } from ":trpc/server"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; import { AuthError } from "@1.modules/core/errors"; import { PROFILE_ROLES, type Profile } from "@1.modules/profile.domain"; import type { Metadata, ResolvingMetadata } from "next"; @@ -38,7 +38,7 @@ export default async function Page(props: { params: Promise }) { throw new AuthError("No profile id"); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await trpc_server.legacy_profile.by_id.fetch(profile_id); return (
@@ -67,13 +67,17 @@ async function Role_Editor({ return match(role) .with(PROFILE_ROLES.Enum.STUDENT, async () => { const student = - await TRPC_SSR.profile.student.by_profile_id.fetch(profile_id); - const categories = await TRPC_SSR.category.exchange.fetch(); + await trpc_server.legacy_profile.student.by_profile_id.fetch( + profile_id, + ); + const categories = await trpc_server.category.exchange.fetch(); return ; }) .with(PROFILE_ROLES.Enum.PARTNER, async () => { const partner = - await TRPC_SSR.profile.partner.by_profile_id.fetch(profile_id); + await trpc_server.legacy_profile.partner.by_profile_id.fetch( + profile_id, + ); return ; }) .otherwise(() => null); diff --git a/apps/www/app/(main)/door/[code]/(private)/parameters/upload.tsx b/apps/www/app/(main)/door/[code]/(private)/parameters/upload.tsx index 232f3445b..50530b70a 100644 --- a/apps/www/app/(main)/door/[code]/(private)/parameters/upload.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/parameters/upload.tsx @@ -21,8 +21,11 @@ export async function uploadImage(formData: FormData) { token, }); - const profile = await proxyClient.profile.by_id.query(profile_id); - await proxyClient.profile.me.update.mutate({ ...profile, image: blob.url }); + const profile = await proxyClient.legacy_profile.by_id.query(profile_id); + await proxyClient.legacy_profile.me.update.mutate({ + ...profile, + image: blob.url, + }); revalidatePath( `https://xliajqivstyuw7e1.public.blob.vercel-storage.com/${pathname}`, diff --git a/apps/www/app/(main)/door/[code]/(private)/welcome/page.client.tsx b/apps/www/app/(main)/door/[code]/(private)/welcome/page.client.tsx deleted file mode 100644 index 61ad72ec2..000000000 --- a/apps/www/app/(main)/door/[code]/(private)/welcome/page.client.tsx +++ /dev/null @@ -1,19 +0,0 @@ -"use client"; - -import { useSession } from "@1.modules/auth.next/react"; -import { Avatar } from "@1.ui/react/avatar"; - -// - -export default function Welcome_Flow() { - const { data: session } = useSession({ required: true }); - - return ( - <> -
- -

{session?.profile?.name}

-
- - ); -} diff --git a/apps/www/app/(main)/door/[code]/(private)/welcome/page.tsx b/apps/www/app/(main)/door/[code]/(private)/welcome/page.tsx index 7c8352473..405103135 100644 --- a/apps/www/app/(main)/door/[code]/(private)/welcome/page.tsx +++ b/apps/www/app/(main)/door/[code]/(private)/welcome/page.tsx @@ -1,16 +1,9 @@ // -import { Spinner } from "@1.ui/react/spinner"; import type { Metadata, ResolvingMetadata } from "next"; -import dynamic from "next/dynamic"; - -// - -const Welcome_Flow = dynamic(() => import("./page.client"), { - loading() { - return ; - }, -}); +import { Avatar } from "@1.ui/react/avatar"; +import { auth } from "@1.modules/auth.next"; +import { ProfileAvatarMedia } from ":components/avatar"; // @@ -31,6 +24,8 @@ export async function generateMetadata( // export default async function Page() { + const session = await auth(); + if (!session) return null; return (

- +

); diff --git a/apps/www/app/(main)/door/[code]/(public)/(about)/page.tsx b/apps/www/app/(main)/door/[code]/(public)/(about)/page.tsx index 60704f8bc..9fa76acf9 100644 --- a/apps/www/app/(main)/door/[code]/(public)/(about)/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/(about)/page.tsx @@ -30,7 +30,7 @@ export default async function Page(props: { params: Promise }) { throw new AuthError("No profile id"); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); return (
@@ -60,7 +60,7 @@ export default async function Page(props: { params: Promise }) { async function StudentMeta({ profile_id }: { profile_id: string }) { const student = - await TRPC_SSR.profile.student.by_profile_id.fetch(profile_id); + await TRPC_SSR.legacy_profile.student.by_profile_id.fetch(profile_id); return (
    @@ -83,7 +83,7 @@ async function StudentMeta({ profile_id }: { profile_id: string }) { async function PartnerMeta({ profile_id }: { profile_id: string }) { const partner = - await TRPC_SSR.profile.partner.by_profile_id.fetch(profile_id); + await TRPC_SSR.legacy_profile.partner.by_profile_id.fetch(profile_id); return (
      diff --git a/apps/www/app/(main)/door/[code]/(public)/@header/AddedByCount.tsx b/apps/www/app/(main)/door/[code]/(public)/@header/AddedByCount.tsx index f4d466129..b747fd4b0 100644 --- a/apps/www/app/(main)/door/[code]/(public)/@header/AddedByCount.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/@header/AddedByCount.tsx @@ -5,7 +5,7 @@ import { TRPC_React } from ":trpc/client"; // export function AddedByCount({ profile_id }: { profile_id: string }) { - const profile = TRPC_React.profile.by_id.useQuery(profile_id); + const profile = TRPC_React.legacy_profile.by_id.useQuery(profile_id); const count = profile.data?.in_contact_with.length ?? 0; return (
      diff --git a/apps/www/app/(main)/door/[code]/(public)/@header/CircleCount.tsx b/apps/www/app/(main)/door/[code]/(public)/@header/CircleCount.tsx index d40b258dd..48d436311 100644 --- a/apps/www/app/(main)/door/[code]/(public)/@header/CircleCount.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/@header/CircleCount.tsx @@ -5,7 +5,7 @@ import { TRPC_React } from ":trpc/client"; // export function CircleCount({ profile_id }: { profile_id: string }) { - const profile = TRPC_React.profile.by_id.useQuery(profile_id); + const profile = TRPC_React.legacy_profile.by_id.useQuery(profile_id); const count = profile.data?.contacts.length ?? 0; return (
      diff --git a/apps/www/app/(main)/door/[code]/(public)/@header/default.tsx b/apps/www/app/(main)/door/[code]/(public)/@header/default.tsx index 56c8dd0f0..25f57e04b 100644 --- a/apps/www/app/(main)/door/[code]/(public)/@header/default.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/@header/default.tsx @@ -27,13 +27,13 @@ export default async function Page(props: { params: Promise }) { throw new AuthError("Unkwon code", { cause: code_to_profile_id_err }); } const [profile_err, profile] = await to( - TRPC_SSR.profile.by_id.fetch(profile_id), + TRPC_SSR.legacy_profile.by_id.fetch(profile_id), ); if (!profile) { throw new AuthError("No profile", { cause: profile_err }); } - await TRPC_SSR.profile.by_id.prefetch(profile_id); + await TRPC_SSR.legacy_profile.by_id.prefetch(profile_id); return ( @@ -67,13 +67,13 @@ async function MaybeProfileLink( function ProfileAvatar({ profile }: { profile: Profile }) { return match(profile.role) .with(PROFILE_ROLES.Enum.STUDENT, async () => { - const student = await TRPC_SSR.profile.student.by_profile_id.fetch( + const student = await TRPC_SSR.legacy_profile.student.by_profile_id.fetch( profile.id, ); return ; }) .with(PROFILE_ROLES.Enum.PARTNER, async () => { - const partner = await TRPC_SSR.profile.partner.by_profile_id.fetch( + const partner = await TRPC_SSR.legacy_profile.partner.by_profile_id.fetch( profile.id, ); return ; diff --git a/apps/www/app/(main)/door/[code]/(public)/@navbar/_client/AddContact.tsx b/apps/www/app/(main)/door/[code]/(public)/@navbar/_client/AddContact.tsx index 766af0971..6a4ca9f8e 100644 --- a/apps/www/app/(main)/door/[code]/(public)/@navbar/_client/AddContact.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/@navbar/_client/AddContact.tsx @@ -20,23 +20,27 @@ export default function AddContact({ }) { const { data: session } = useSession(); const find_contact = - TRPC_React.profile.me.contact.find_by_profile_id.useQuery(profile_id, { - staleTime: Infinity, - }); - const toggle_contact = TRPC_React.profile.me.contact.toggle.useMutation(); + TRPC_React.legacy_profile.me.contact.find_by_profile_id.useQuery( + profile_id, + { + staleTime: Infinity, + }, + ); + const toggle_contact = + TRPC_React.legacy_profile.me.contact.toggle.useMutation(); const utils = TRPC_React.useUtils(); const { is_blocked } = useBlockProfile(profile_id); const toggle_add_contact = useCallback(async () => { await toggle_contact.mutateAsync(profile_id); await Promise.all([ - utils.profile.by_id.invalidate(profile_id), - utils.profile.by_id.invalidate(session?.profile.id), + utils.legacy_profile.by_id.invalidate(profile_id), + utils.legacy_profile.by_id.invalidate(session?.profile.id), - utils.profile.me.added_by.find.invalidate(), - utils.profile.me.contact.find_by_profile_id.invalidate(profile_id), + utils.legacy_profile.me.added_by.find.invalidate(), + utils.legacy_profile.me.contact.find_by_profile_id.invalidate(profile_id), - utils.profile.me.contacts.invalidate({}), + utils.legacy_profile.me.contacts.invalidate({}), ]); toggle_contact.reset(); }, [toggle_contact, utils, profile_id]); diff --git a/apps/www/app/(main)/door/[code]/(public)/@navbar/default.tsx b/apps/www/app/(main)/door/[code]/(public)/@navbar/default.tsx index a150d5fc2..2bfc16a2f 100644 --- a/apps/www/app/(main)/door/[code]/(public)/@navbar/default.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/@navbar/default.tsx @@ -19,7 +19,7 @@ export default async function Page(props: { params: Promise }) { } const param = { ...params, profile_id }; - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); return match(profile.role) .with(PROFILE_ROLES.Enum.PARTNER, () => ) diff --git a/apps/www/app/(main)/door/[code]/(public)/contacts/_client/Infinite_Contacts_List.tsx b/apps/www/app/(main)/door/[code]/(public)/contacts/_client/Infinite_Contacts_List.tsx index 0ab9b5327..79857698a 100644 --- a/apps/www/app/(main)/door/[code]/(public)/contacts/_client/Infinite_Contacts_List.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/contacts/_client/Infinite_Contacts_List.tsx @@ -13,7 +13,7 @@ import Loading_Placeholder from "../loading"; // function useQueryContacts() { - return TRPC_React.profile.me.contacts.useInfiniteQuery( + return TRPC_React.legacy_profile.me.contacts.useInfiniteQuery( {}, { getNextPageParam: ({ next_cursor }) => next_cursor }, ); diff --git a/apps/www/app/(main)/door/[code]/(public)/contacts/page.tsx b/apps/www/app/(main)/door/[code]/(public)/contacts/page.tsx index 506a7ff15..56176173c 100644 --- a/apps/www/app/(main)/door/[code]/(public)/contacts/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/contacts/page.tsx @@ -31,7 +31,7 @@ export default async function Page(props: { params: Promise }) { redirect(`/@${params.code}`); } - await TRPC_SSR.profile.me.contacts.prefetchInfinite({}); + await TRPC_SSR.legacy_profile.me.contacts.prefetchInfinite({}); return (
      diff --git a/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx b/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx index ef49a6dec..6d6114ddf 100644 --- a/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/following/_client/List.tsx @@ -14,7 +14,7 @@ import { P, match } from "ts-pattern"; // function useQueryProfilesFollowingMe() { - return TRPC_React.profile.me.added_by.find.useInfiniteQuery( + return TRPC_React.legacy_profile.me.added_by.find.useInfiniteQuery( {}, { getNextPageParam: ({ next_cursor }) => next_cursor }, ); diff --git a/apps/www/app/(main)/door/[code]/(public)/following/page.tsx b/apps/www/app/(main)/door/[code]/(public)/following/page.tsx index f6465f0fc..0260c806e 100644 --- a/apps/www/app/(main)/door/[code]/(public)/following/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/following/page.tsx @@ -31,7 +31,7 @@ export default async function Page(props: { params: Promise }) { redirect(`/@${params.code}`); } - await TRPC_SSR.profile.me.added_by.find.prefetchInfinite({}); + await TRPC_SSR.legacy_profile.me.added_by.find.prefetchInfinite({}); return (
      diff --git a/apps/www/app/(main)/door/[code]/(public)/history/page.tsx b/apps/www/app/(main)/door/[code]/(public)/history/page.tsx index 26ffe3ca7..5f2eb21fa 100644 --- a/apps/www/app/(main)/door/[code]/(public)/history/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/history/page.tsx @@ -28,7 +28,7 @@ export default async function Page(props: { params: Promise }) { notFound(); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); if (profile.role !== PROFILE_ROLES.Enum.STUDENT) { redirect(`/@${params.code}`); } diff --git a/apps/www/app/(main)/door/[code]/(public)/opportunities/page.tsx b/apps/www/app/(main)/door/[code]/(public)/opportunities/page.tsx index 75b20296d..0560176a8 100644 --- a/apps/www/app/(main)/door/[code]/(public)/opportunities/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/opportunities/page.tsx @@ -26,7 +26,7 @@ export default async function Page(props: { params: Promise }) { return notFound(); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await TRPC_SSR.legacy_profile.by_id.fetch(profile_id); if (profile.role !== PROFILE_ROLES.Enum.PARTNER) { redirect(`/@${params.code}`); } diff --git a/apps/www/app/(main)/door/[code]/(public)/proposals/layout.tsx b/apps/www/app/(main)/door/[code]/(public)/proposals/layout.tsx new file mode 100644 index 000000000..c0c75cf46 --- /dev/null +++ b/apps/www/app/(main)/door/[code]/(public)/proposals/layout.tsx @@ -0,0 +1,8 @@ +// + +import { TrpcRootProvider } from ":trpc/root"; +import type { PropsWithChildren } from "react"; + +export default function Layout({ children }: PropsWithChildren) { + return {children}; +} diff --git a/apps/www/app/(main)/door/[code]/(public)/proposals/page.tsx b/apps/www/app/(main)/door/[code]/(public)/proposals/page.tsx index d6991e4fe..566c39103 100644 --- a/apps/www/app/(main)/door/[code]/(public)/proposals/page.tsx +++ b/apps/www/app/(main)/door/[code]/(public)/proposals/page.tsx @@ -2,9 +2,10 @@ import { NotConnected_Placeholder } from ":components/placeholder/NotConnected_Placeholder"; import { code_to_profile_id, type CodeParms } from ":pipes/code"; -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; import { Exchange_Card } from ":widgets/exchanges/card"; -import { getServerSession } from "@1.modules/auth.next"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; +import { auth } from "@1.modules/auth.next"; import { PROFILE_ROLES } from "@1.modules/profile.domain"; import type { Metadata, ResolvingMetadata } from "next"; import { notFound, redirect } from "next/navigation"; @@ -27,16 +28,16 @@ export default async function Page(props: { params: Promise }) { return notFound(); } - const profile = await TRPC_SSR.profile.by_id.fetch(profile_id); + const profile = await trpc_server.profile.by_id.fetch(profile_id); if (profile.role !== PROFILE_ROLES.Enum.STUDENT) { redirect(`/@${params.code}`); } - const { data: exchanges } = await TRPC_SSR.exchanges.by_profile.fetch({ + const { data: exchanges } = await trpc_server.exchanges.by_profile.fetch({ profile_id, }); - const session = await getServerSession(); + const session = await auth(); if (!session) { return ; diff --git a/apps/www/app/(main)/door/[code]/@navbar/default.tsx b/apps/www/app/(main)/door/[code]/@navbar/default.tsx index 8226fb393..65f5f38b9 100644 --- a/apps/www/app/(main)/door/[code]/@navbar/default.tsx +++ b/apps/www/app/(main)/door/[code]/@navbar/default.tsx @@ -26,16 +26,16 @@ export default async function Page(props: { params: Promise }) { return await match({ is_yours, role }) .with({ role: PROFILE_ROLES.Enum.STUDENT, is_yours: true }, async () => { const student = - await TRPC_SSR.profile.student.by_profile_id.fetch(profile_id); + await TRPC_SSR.legacy_profile.student.by_profile_id.fetch(profile_id); return ; }) .with({ role: PROFILE_ROLES.Enum.PARTNER, is_yours: true }, async () => { const partner = - await TRPC_SSR.profile.partner.by_profile_id.fetch(profile_id); + await TRPC_SSR.legacy_profile.partner.by_profile_id.fetch(profile_id); return ; }) .otherwise(() => null); - } catch (error) { + } catch { return notFound(); } } diff --git a/apps/www/app/(main)/door/[code]/report/action.ts b/apps/www/app/(main)/door/[code]/report/action.ts index f61c4c6e6..4556ffb0f 100644 --- a/apps/www/app/(main)/door/[code]/report/action.ts +++ b/apps/www/app/(main)/door/[code]/report/action.ts @@ -42,7 +42,7 @@ export async function report( const input = validatedFields.data; - const [report_error] = await to(trpc_caller.profile.me.report(input)); + const [report_error] = await to(trpc_caller.legacy_profile.me.report(input)); if (report_error) { return { ...state, diff --git a/apps/www/app/(main)/exchanges/[exchange_id]/Card.tsx b/apps/www/app/(main)/exchanges/[exchange_id]/Card.tsx index 738ad2d7e..07f82b956 100644 --- a/apps/www/app/(main)/exchanges/[exchange_id]/Card.tsx +++ b/apps/www/app/(main)/exchanges/[exchange_id]/Card.tsx @@ -2,8 +2,8 @@ import { Loading_Placeholder } from ":components/placeholder/Loading_Placeholder"; import type { Params } from ":pipes/exchange_by_id"; -import { TRPC_React } from ":trpc/client"; import { Exchange_Card } from ":widgets/exchanges/card"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { useSession } from "@1.modules/auth.next/react"; import { notFound } from "next/navigation"; import { match, P } from "ts-pattern"; @@ -13,7 +13,7 @@ import { match, P } from "ts-pattern"; export function Card({ exchange_id }: Params) { const { data: session } = useSession(); const { data: exchange, status } = - TRPC_React.exchanges.by_id.useQuery(exchange_id); + trpc_client.exchanges.by_id.useQuery(exchange_id); return match({ exchange, status }) .with({ status: "error" }, () => notFound()) diff --git a/apps/www/app/(main)/exchanges/[exchange_id]/layout.tsx b/apps/www/app/(main)/exchanges/[exchange_id]/layout.tsx index e09061673..d5aaff9fa 100644 --- a/apps/www/app/(main)/exchanges/[exchange_id]/layout.tsx +++ b/apps/www/app/(main)/exchanges/[exchange_id]/layout.tsx @@ -1,7 +1,8 @@ // import type { Params } from ":pipes/exchange_by_id"; -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; import { notFound } from "next/navigation"; import type { PropsWithChildren } from "react"; @@ -16,7 +17,7 @@ export default async function Layout( const { exchange_id } = params; try { - await TRPC_SSR.exchanges.by_id.prefetch(exchange_id); + await trpc_server.exchanges.by_id.prefetch(exchange_id); } catch { notFound(); } diff --git a/apps/www/app/(main)/exchanges/[exchange_id]/page.tsx b/apps/www/app/(main)/exchanges/[exchange_id]/page.tsx index 11c65877a..ac6d7fe10 100644 --- a/apps/www/app/(main)/exchanges/[exchange_id]/page.tsx +++ b/apps/www/app/(main)/exchanges/[exchange_id]/page.tsx @@ -1,10 +1,10 @@ // import type { Params } from ":pipes/exchange_by_id"; -import { TRPC_SSR } from ":trpc/server"; import to from "await-to-js"; import type { Metadata, ResolvingMetadata } from "next"; import { Card } from "./Card"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; // @@ -16,7 +16,7 @@ export async function generateMetadata( const { exchange_id } = params; - const [, exchange] = await to(TRPC_SSR.exchanges.by_id.fetch(exchange_id)); + const [, exchange] = await to(trpc_server.exchanges.by_id.fetch(exchange_id)); const title = exchange?.title ?? "Not Found"; return { diff --git a/apps/www/app/(main)/exchanges/layout.tsx b/apps/www/app/(main)/exchanges/layout.tsx index 20f1affc5..47cf92510 100644 --- a/apps/www/app/(main)/exchanges/layout.tsx +++ b/apps/www/app/(main)/exchanges/layout.tsx @@ -1,6 +1,7 @@ /// import { AsideFilter } from ":components/shell/AsideFilter"; +import { TrpcRootProvider } from ":trpc/root"; import { Exchanges_Filter } from ":widgets/exchanges/filter"; import { SearchForm } from ":widgets/exchanges/list"; import { Grid } from "@1.ui/react/grid"; @@ -27,10 +28,12 @@ export default async function Layout({ {categories} -
      {children}
      - {/* */} + +
      {children}
      +
      + ); } diff --git a/apps/www/app/(main)/exchanges/page.tsx b/apps/www/app/(main)/exchanges/page.tsx index 25ec083db..a0f932aac 100644 --- a/apps/www/app/(main)/exchanges/page.tsx +++ b/apps/www/app/(main)/exchanges/page.tsx @@ -1,5 +1,6 @@ // +import { TrpcRootProvider } from ":trpc/root"; import { TRPC_Hydrate } from ":trpc/server"; import { List } from ":widgets/exchanges/list"; import { trpc_server } from "@1.infra/trpc/react-query/server"; @@ -50,13 +51,15 @@ export default async function Page({ }); return ( - -
      - + + +
      + - -
      -
      + +
      +
      + ); } diff --git a/apps/www/app/(main)/forum/_client/List.tsx b/apps/www/app/(main)/forum/_client/List.tsx index 69f8c17a5..3fe6fd8da 100644 --- a/apps/www/app/(main)/forum/_client/List.tsx +++ b/apps/www/app/(main)/forum/_client/List.tsx @@ -138,7 +138,7 @@ function Delete_Answer_Button() { const is_owner = session.data?.profile.id === answer.owner.profile.id; async function deleteAnswer() { - await mutateAsync(answer.id); + await mutateAsync({ answers_id: answer.id, question_id: answer.parent_id }); await utils.forum.question.answers.find.invalidate(); } diff --git a/apps/www/app/(main)/forum/layout.tsx b/apps/www/app/(main)/forum/layout.tsx index 1b59091a1..1286e785b 100644 --- a/apps/www/app/(main)/forum/layout.tsx +++ b/apps/www/app/(main)/forum/layout.tsx @@ -1,6 +1,7 @@ // import { AsideFilter } from ":components/shell/AsideFilter"; +import { TrpcRootProvider } from ":trpc/root"; import { Grid } from "@1.ui/react/grid"; import InputSearch from "@1.ui/react/input/InputSearch"; import dynamic from "next/dynamic"; @@ -33,10 +34,13 @@ export default async function Layout({ {categories} -
      {children}
      - + + +
      {children}
      + +
      ); } diff --git a/apps/www/app/(main)/layout.tsx b/apps/www/app/(main)/layout.tsx index fa5dea27b..0654d0ac3 100644 --- a/apps/www/app/(main)/layout.tsx +++ b/apps/www/app/(main)/layout.tsx @@ -5,7 +5,7 @@ import { MobileNavBar } from ":components/shell/MobileNavBar"; import { TermAgreement } from ":components/terms/TermAgreement"; import type { PropsWithChildren } from "react"; import { tv } from "tailwind-variants"; -import Header from "./navbar"; +import UserBar from ":components/navbar/UserBar"; // @@ -14,7 +14,7 @@ export default function Main_Layout({ children }: PropsWithChildren) { return (
      -
      +
      {children} diff --git a/apps/www/app/(main)/opportunities/[slug]/@see_also/page.tsx b/apps/www/app/(main)/opportunities/[slug]/@see_also/page.tsx index d5ef30157..cc40b98ea 100644 --- a/apps/www/app/(main)/opportunities/[slug]/@see_also/page.tsx +++ b/apps/www/app/(main)/opportunities/[slug]/@see_also/page.tsx @@ -1,7 +1,8 @@ // import type { Params } from ":pipes/opportunity_slug"; -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; import { SeeAlso_Provider } from "./context"; import Page_Client from "./page.client"; @@ -10,13 +11,13 @@ import Page_Client from "./page.client"; export default async function Page({ params }: { params: Params }) { const { slug } = await params; - const opportunity = await TRPC_SSR.opportunity.by_slug.fetch(slug); + const opportunity = await trpc_server.opportunity.by_slug.fetch(slug); const { id, category: { slug: category }, } = opportunity; - await TRPC_SSR.opportunity.find.prefetchInfinite({ + await trpc_server.opportunity.find.prefetchInfinite({ category, limit: 5, }); diff --git a/apps/www/app/(main)/opportunities/[slug]/delete.tsx b/apps/www/app/(main)/opportunities/[slug]/delete.tsx index fbd36cbef..8036ada2b 100644 --- a/apps/www/app/(main)/opportunities/[slug]/delete.tsx +++ b/apps/www/app/(main)/opportunities/[slug]/delete.tsx @@ -1,6 +1,6 @@ "use client"; -import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { Button } from "@1.ui/react/button"; import { Trash } from "@1.ui/react/icons"; import { Spinner } from "@1.ui/react/spinner"; @@ -78,9 +78,9 @@ function Idle() { function Deleting() { const { id: opportunity_id } = useOpportunity(); - const delete_opportunity = TRPC_React.opportunity.delete.useMutation(); + const delete_opportunity = trpc_client.opportunity.delete.useMutation(); const router = useRouter(); - const utils = TRPC_React.useUtils(); + const utils = trpc_client.useUtils(); useTimeoutEffect(async () => { await delete_opportunity.mutateAsync(opportunity_id); diff --git a/apps/www/app/(main)/opportunities/[slug]/layout.tsx b/apps/www/app/(main)/opportunities/[slug]/layout.tsx index 735097b6f..0cd085705 100644 --- a/apps/www/app/(main)/opportunities/[slug]/layout.tsx +++ b/apps/www/app/(main)/opportunities/[slug]/layout.tsx @@ -1,8 +1,8 @@ // +import { TrpcRootProvider } from ":trpc/root"; import { Grid } from "@1.ui/react/grid"; import { type PropsWithChildren } from "react"; -// import SeeAlso_Page from "./@see_also/page"; // @@ -15,8 +15,10 @@ export default async function Opoortunity_Layout({ fluid className=" bg-white md:col-span-6 md:bg-transparent xl:col-span-9" > -
      {children}
      - + +
      {children}
      + +
      ); } diff --git a/apps/www/app/(main)/opportunities/_client/List.tsx b/apps/www/app/(main)/opportunities/_client/List.tsx index 29b34a48e..3e33b817a 100644 --- a/apps/www/app/(main)/opportunities/_client/List.tsx +++ b/apps/www/app/(main)/opportunities/_client/List.tsx @@ -1,7 +1,7 @@ "use client"; -import { TRPC_React } from ":trpc/client"; import { Card } from ":widgets/opportunities/card"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { Partner_Filter } from "@1.modules/opportunity.domain"; import { Opportunity_InfiniteList } from "@1.modules/opportunity.ui/InfiniteList"; import { useSearchParams } from "next/navigation"; @@ -22,7 +22,7 @@ export default function List() { gtag("event", "search", { search, category, filter }); }, [search, category, filter]); - const info = TRPC_React.opportunity.find.useInfiniteQuery( + const info = trpc_client.opportunity.find.useInfiniteQuery( { category, search, diff --git a/apps/www/app/(main)/opportunities/layout.tsx b/apps/www/app/(main)/opportunities/layout.tsx index 30d032192..0e7910f2a 100644 --- a/apps/www/app/(main)/opportunities/layout.tsx +++ b/apps/www/app/(main)/opportunities/layout.tsx @@ -9,6 +9,7 @@ import { match } from "ts-pattern"; import { Partner_Opportunities_Filter } from "./_client/Partner_Opportunities_Filter"; import SearchForm from "./_client/SearchForm"; import Loading from "./loading"; +import { TrpcRootProvider } from ":trpc/root"; // @@ -28,12 +29,14 @@ export default async function Layout({
      - {categories} + {categories} -
      - {children} -
      + +
      + {children} +
      +
      ); } diff --git a/apps/www/app/(main)/opportunities/page.tsx b/apps/www/app/(main)/opportunities/page.tsx index 0c7236066..950352f6e 100644 --- a/apps/www/app/(main)/opportunities/page.tsx +++ b/apps/www/app/(main)/opportunities/page.tsx @@ -1,6 +1,6 @@ // -import { TRPC_Hydrate, TRPC_SSR } from ":trpc/server"; +import { TRPC_Hydrate } from ":trpc/server"; import { Partner_Filter, type OpportunitySearchParams, @@ -8,6 +8,7 @@ import { import type { _1_HOUR_ } from "@douglasduteil/datatypes...hours-to-seconds"; import type { Metadata, ResolvingMetadata } from "next"; import List from "./_client/List"; +import { trpc_server } from "@1.infra/trpc/react-query/server"; // @@ -42,7 +43,7 @@ export default async function Page({ ? filter_parsed_return.data : undefined; - await TRPC_SSR.opportunity.find.prefetchInfinite({ + await trpc_server.opportunity.find.prefetchInfinite({ category, filter, search, diff --git a/apps/www/components/Share_Button.tsx b/apps/www/components/Share_Button.tsx index 927c2f8d1..073c5eaad 100644 --- a/apps/www/components/Share_Button.tsx +++ b/apps/www/components/Share_Button.tsx @@ -24,6 +24,7 @@ export function Share_Button({ 5_000, ); const copy_to_clipboard = useCallback(async () => { + if (!navigator.clipboard) return; await navigator.clipboard.writeText( href.startsWith("/") ? `${window.location.origin}${href}` : href, ); diff --git a/apps/www/components/avatar/index.tsx b/apps/www/components/avatar/index.tsx index 5049616e9..3176f87a2 100644 --- a/apps/www/components/avatar/index.tsx +++ b/apps/www/components/avatar/index.tsx @@ -2,6 +2,7 @@ import type { AvatarProfile } from "@1.modules/profile.domain"; import { AvatarMedia, type AvatarMediaProps } from "@1.ui/react/avatar"; +import type { AvatarMediaVariantProps } from "@1.ui/react/avatar/atom"; import Link from "next/link"; // @@ -25,10 +26,11 @@ export function SeeProfileAvatarMedia( ); } -export function ProfileAvatarMedia( - props: AvatarMediaProps & { profile: AvatarProfile }, -) { - const { profile, ...other_props } = props; +export function ProfileAvatarMedia(props: { + profile: AvatarProfile; + variant?: AvatarMediaVariantProps; +}) { + const { profile, variant, ...other_props } = props; return ( ); diff --git a/apps/www/components/button/AddToMyCircles.tsx b/apps/www/components/button/AddToMyCircles.tsx index 168ebe002..0a4bab5a9 100644 --- a/apps/www/components/button/AddToMyCircles.tsx +++ b/apps/www/components/button/AddToMyCircles.tsx @@ -10,8 +10,11 @@ import { match, P } from "ts-pattern"; export function AddToMyCircles({ profile_id }: { profile_id: string }) { const find_contact = - TRPC_React.profile.me.contact.find_by_profile_id.useQuery(profile_id); - const toggle_contact = TRPC_React.profile.me.contact.toggle.useMutation(); + TRPC_React.legacy_profile.me.contact.find_by_profile_id.useQuery( + profile_id, + ); + const toggle_contact = + TRPC_React.legacy_profile.me.contact.toggle.useMutation(); const utils = TRPC_React.useUtils(); const { is_blocked } = useBlockProfile(profile_id); @@ -19,8 +22,8 @@ export function AddToMyCircles({ profile_id }: { profile_id: string }) { await toggle_contact.mutateAsync(profile_id); await Promise.all([ utils.exchanges.find.invalidate({ category: "MY_CIRCLES" }), - utils.profile.me.contact.find_by_profile_id.invalidate(profile_id), - utils.profile.me.contacts.invalidate({}), + utils.legacy_profile.me.contact.find_by_profile_id.invalidate(profile_id), + utils.legacy_profile.me.contacts.invalidate({}), ]); toggle_contact.reset(); }, [toggle_contact, utils, profile_id]); diff --git a/apps/www/components/button/BlockProfile.tsx b/apps/www/components/button/BlockProfile.tsx index 456c89235..312169d79 100644 --- a/apps/www/components/button/BlockProfile.tsx +++ b/apps/www/components/button/BlockProfile.tsx @@ -42,16 +42,17 @@ export function BlockProfile({ profile_id }: { profile_id: ID_Schema }) { } export function useBlockProfile(profile_id: ID_Schema) { - const find_profile = TRPC_React.profile.me.blacklist.find.useQuery({ + const find_profile = TRPC_React.legacy_profile.me.blacklist.find.useQuery({ profile_id, }); - const toggle_mutation = TRPC_React.profile.me.blacklist.toggle.useMutation(); + const toggle_mutation = + TRPC_React.legacy_profile.me.blacklist.toggle.useMutation(); const utils = TRPC_React.useUtils(); const toggle_add_to_blacklist = useCallback(async () => { await toggle_mutation.mutateAsync({ profile_id }); await Promise.all([ - utils.profile.me.blacklist.find.refetch({ profile_id }), + utils.legacy_profile.me.blacklist.find.refetch({ profile_id }), utils.invalidate(), ]); toggle_mutation.reset(); diff --git a/apps/www/app/(main)/navbar.client.tsx b/apps/www/components/navbar/UserBar.client.tsx similarity index 94% rename from apps/www/app/(main)/navbar.client.tsx rename to apps/www/components/navbar/UserBar.client.tsx index f4cb379c3..b52974f20 100644 --- a/apps/www/app/(main)/navbar.client.tsx +++ b/apps/www/components/navbar/UserBar.client.tsx @@ -1,13 +1,10 @@ "use client"; -import { - Partner_NavBar, - Student_NavBar, -} from ":components/navbar/aside_navbar"; +import { Partner_NavBar, Student_NavBar } from "./aside_navbar"; import type { Partner, Student } from "@1.modules/profile.domain"; import { useToggle } from "@react-hookz/web"; - import { type PropsWithChildren, type ReactNode } from "react"; + // export function UserMenuToggleStudent({ student, diff --git a/apps/www/app/(main)/navbar.tsx b/apps/www/components/navbar/UserBar.tsx similarity index 93% rename from apps/www/app/(main)/navbar.tsx rename to apps/www/components/navbar/UserBar.tsx index e0fd2f7da..570566a89 100644 --- a/apps/www/app/(main)/navbar.tsx +++ b/apps/www/components/navbar/UserBar.tsx @@ -6,6 +6,7 @@ import { Notification_DotIndicator, } from ":components/navbar/notification_indicator.client"; import { MobileNavBar } from ":components/shell/MobileNavBar"; +import { TrpcRootProvider } from ":trpc/root"; import { TRPC_SSR } from ":trpc/server"; import { auth } from "@1.modules/auth.next"; import { PROFILE_ROLES, type AuthProfile } from "@1.modules/profile.domain"; @@ -17,7 +18,7 @@ import Link from "next/link"; import { type ComponentPropsWithoutRef } from "react"; import { tv } from "tailwind-variants"; import { match } from "ts-pattern"; -import { UserMenuTogglePartner, UserMenuToggleStudent } from "./navbar.client"; +import { UserMenuTogglePartner, UserMenuToggleStudent } from "./UserBar.client"; // @@ -32,8 +33,9 @@ export default function UserBar() { - - + + +
      ); @@ -107,7 +109,7 @@ const user_nav_group_variants = tv( }, ); async function MyStudentProfile({ profile }: { profile: AuthProfile }) { - const student = await TRPC_SSR.profile.student?.by_profile_id.fetch( + const student = await TRPC_SSR.legacy_profile.student?.by_profile_id.fetch( profile.id, ); @@ -139,7 +141,7 @@ async function MyStudentProfile({ profile }: { profile: AuthProfile }) { } async function MyPartnerProfile({ profile }: { profile: AuthProfile }) { - const partner = await TRPC_SSR.profile.partner?.by_profile_id.fetch( + const partner = await TRPC_SSR.legacy_profile.partner?.by_profile_id.fetch( profile.id, ); diff --git a/apps/www/components/navbar/aside_navbar.tsx b/apps/www/components/navbar/aside_navbar.tsx index 52b2b7c8e..6b27d9d01 100644 --- a/apps/www/components/navbar/aside_navbar.tsx +++ b/apps/www/components/navbar/aside_navbar.tsx @@ -23,6 +23,7 @@ import { NewsInExchange_Indicator, NewsInMessage_Indicator, } from "./notification_indicator.client"; +import { TrpcRootProvider } from ":trpc/root"; // @@ -50,7 +51,9 @@ export function Student_NavBar({ href="./exchanges/inbox" > Cercles d'échanges - + + + } href="./inbox"> Messages privés - + + + - {children} + {children} diff --git a/apps/www/widgets/exchanges/card/actions.tsx b/apps/www/widgets/exchanges/card/actions.tsx index 2a537f241..6e6ec68ce 100644 --- a/apps/www/widgets/exchanges/card/actions.tsx +++ b/apps/www/widgets/exchanges/card/actions.tsx @@ -1,6 +1,6 @@ // -import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { useSession } from "@1.modules/auth.next/react"; import { Exchange_TypeSchema, type Exchange } from "@1.modules/exchange.domain"; import { Exchange_Ask_Modal } from "@1.modules/exchange.ui/ask/modal"; @@ -32,7 +32,7 @@ export function Exchange_Actions() { function Exchange_Action_Ask(exchange: Exchange) { const { is_studient } = useExchangeMeta(); - const query = TRPC_React.exchanges.me.deal_by_exchange_id.useQuery( + const query = trpc_client.exchanges.me.deal_by_exchange_id.useQuery( exchange.id, { enabled: is_studient }, ); diff --git a/apps/www/widgets/exchanges/card/bookmark.tsx b/apps/www/widgets/exchanges/card/bookmark.tsx index 8b464cc5b..4631ebcae 100644 --- a/apps/www/widgets/exchanges/card/bookmark.tsx +++ b/apps/www/widgets/exchanges/card/bookmark.tsx @@ -1,7 +1,7 @@ // import { AppToastOptions } from ":components/toast"; -import { TRPC_React } from ":trpc/client"; +import { trpc_client } from "@1.infra/trpc/react-query/client"; import { useSession } from "@1.modules/auth.next/react"; import type { BookmarkButton_Props } from "@1.modules/bookmark.ui/BookmarkButton"; import { useExchange } from "@1.modules/exchange.ui/Card/context"; @@ -21,7 +21,7 @@ export function Exchange_Bookmark() { const { data: session } = useSession(); const is_student = session?.profile.role === PROFILE_ROLES.Enum.STUDENT; - const query = TRPC_React.bookmarks.check.useQuery( + const query = trpc_client.bookmarks.check.useQuery( { target_id: exchange.id, type: "exchange", @@ -54,8 +54,8 @@ export function Exchange_Bookmark() { function BookmarkItem_Toggle_Mutation(props: BookmarkButton_Props) { const { className, target_id, type, variants } = props; - const toggle = TRPC_React.bookmarks.toggle.useMutation(); - const utils = TRPC_React.useUtils(); + const toggle = trpc_client.bookmarks.toggle.useMutation(); + const utils = trpc_client.useUtils(); const { base, icon } = style({ ...variants }); return ( ); diff --git a/apps/www/widgets/opportunities/card/index.tsx b/apps/www/widgets/opportunities/card/index.tsx index 685de7a49..63883b05c 100644 --- a/apps/www/widgets/opportunities/card/index.tsx +++ b/apps/www/widgets/opportunities/card/index.tsx @@ -52,11 +52,17 @@ export function Card({ opportunity }: { opportunity: CardOportunity }) { function BookmarkItem_Query(props: BookmarkButton_Props) { const { target_id, type } = props; - const query = TRPC_React.bookmarks.check.useQuery({ target_id, type }); + const { data: session } = useSession(); + const is_student = session?.profile.role === PROFILE_ROLES.Enum.STUDENT; + const query = trpc_client.bookmarks.check.useQuery( + { target_id, type }, + { enabled: is_student }, + ); + if (1) return null; return match(query) .with({ status: "error", error: P.select() }, (error) => { - console.error(error); + console.error("trpc_client.bookmarks.check", { error }); return null; }) .with({ status: "loading" }, () => ) diff --git a/packages/@1/modules/bookmark/api/package.json b/packages/@1/modules/bookmark/api/package.json index 5fcd2909b..e1878e9c5 100644 --- a/packages/@1/modules/bookmark/api/package.json +++ b/packages/@1/modules/bookmark/api/package.json @@ -23,6 +23,7 @@ "dependencies": { "@1.modules/bookmark.domain": "workspace:*", "@1.modules/trpc": "workspace:*", + "await-to-js": "3.0.0", "date-fns": "4.1.0", "ts-pattern": "5.5.0", "zod": "3.23.8" diff --git a/packages/@1/modules/bookmark/api/src/check/check.ts b/packages/@1/modules/bookmark/api/src/check/check.ts index e977dea9b..470272916 100644 --- a/packages/@1/modules/bookmark/api/src/check/check.ts +++ b/packages/@1/modules/bookmark/api/src/check/check.ts @@ -1,18 +1,20 @@ // import { Bookmark_Category } from "@1.modules/bookmark.domain"; -import { router } from "@1.modules/trpc"; +import { maybe_session_procedure, router } from "@1.modules/trpc"; +import { to } from "await-to-js"; import { match } from "ts-pattern"; import { z } from "zod"; -import { bookmark_type_procedure } from "../procedure"; // export default router({ - check: bookmark_type_procedure - .input(z.object({ target_id: z.string() })) + check: maybe_session_procedure + .input(z.object({ target_id: z.string(), type: Bookmark_Category })) .query(async ({ ctx: { prisma, session }, input: { target_id, type } }) => { - const { id: owner_id } = session.profile; + const { id: owner_id } = session?.profile ?? {}; + + if (!owner_id) return false; const where = match(type) .with(Bookmark_Category.Enum.exchange, () => ({ @@ -23,9 +25,11 @@ export default router({ })) .exhaustive(); - const count = await prisma.bookmark.count({ - where: { owner_id, ...where }, - }); + const [, count] = await to( + prisma.bookmark.count({ + where: { owner_id, ...where }, + }), + ); return count === 1; }), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f51335994..07da7c8de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -695,6 +695,9 @@ importers: '@1.modules/trpc': specifier: workspace:* version: link:../../trpc + await-to-js: + specifier: 3.0.0 + version: 3.0.0 date-fns: specifier: 4.1.0 version: 4.1.0 diff --git a/serkels.code-workspace b/serkels.code-workspace index 47f4fec35..45d65bd94 100644 --- a/serkels.code-workspace +++ b/serkels.code-workspace @@ -194,6 +194,7 @@ "options": { "cwd": "${workspaceFolder:🚀 www}", "env": { + "NODE_OPTIONS": "--inspect", "NODE_ENV": "development", }, },