From 3a8874c3fb742d84b8a325adb4f159dd2a496ebc Mon Sep 17 00:00:00 2001 From: Dominik Stumpf Date: Sat, 23 Nov 2024 00:02:40 +0100 Subject: [PATCH 01/93] feat: add guild page routes --- guild.d.ts | 33 -------- .../[guildId]/[roleGroupId]/page.tsx | 53 ++++++++++++ .../_components/RoleGroupNavLink.tsx | 25 ++++++ src/app/(dashboard)/[guildId]/layout.tsx | 74 +++++++++++++++++ src/app/(dashboard)/[guildId]/page.tsx | 3 + src/app/explorer/components/GuildCard.tsx | 1 + src/app/explorer/fetchers.ts | 1 + src/app/explorer/page.tsx | 1 + src/app/page.tsx | 10 --- src/components/DashboardContainer.tsx | 27 +++++++ src/lib/types.ts | 80 +++++++++++++++++++ 11 files changed, 265 insertions(+), 43 deletions(-) delete mode 100644 guild.d.ts create mode 100644 src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx create mode 100644 src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx create mode 100644 src/app/(dashboard)/[guildId]/layout.tsx create mode 100644 src/app/(dashboard)/[guildId]/page.tsx delete mode 100644 src/app/page.tsx create mode 100644 src/components/DashboardContainer.tsx create mode 100644 src/lib/types.ts diff --git a/guild.d.ts b/guild.d.ts deleted file mode 100644 index 58eafbad35..0000000000 --- a/guild.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -// dumping here types util it comes down properly - -export {} - -declare global { - type Guild = { - name: string; - id: string; - urlName: string; - createdAt: number; - updatedAt: number; - description: string; - imageUrl: string; - backgroundImageUrl: string; - visibility: Record; - settings: Record; - searchTags: string[]; - categoryTags: string[]; - socialLinks: Record; - owner: string; - }; - - type PaginatedResponse = { - page: number; - pageSize: number; - sortBy: string; - reverse: boolean; - searchQuery: string; - query: string; - items: Item[]; - total: number; - }; -} diff --git a/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx b/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx new file mode 100644 index 0000000000..c3dd83fec7 --- /dev/null +++ b/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx @@ -0,0 +1,53 @@ +import { Card } from "@/components/ui/Card"; +import { env } from "@/lib/env"; +import type { + DynamicRoute, + Guild, + PaginatedResponse, + Role, + RoleGroup, +} from "@/lib/types"; + +const RoleGroupPage = async ({ + params, +}: DynamicRoute<{ roleGroupId: string; guildId: string }>) => { + const { roleGroupId: roleGroupIdParam, guildId: guildIdParam } = await params; + const _guild = (await ( + await fetch(`${env.NEXT_PUBLIC_API}/guild/urlName/${guildIdParam}`) + ).json()) as Guild; + const paginatedRoleGroup = (await ( + await fetch( + `${env.NEXT_PUBLIC_API}/role-group/search?custumQuery=@guildId:{${guildIdParam}}`, + ) + ).json()) as PaginatedResponse; + const roleGroups = paginatedRoleGroup.items; + const roleGroup = roleGroups.find((rg) => rg.urlName === roleGroupIdParam); + + const paginatedRole = (await ( + await fetch( + `${env.NEXT_PUBLIC_API}/role/search?custumQuery=@guildId:{${guildIdParam}} @roleGroupId:{${roleGroup}}`, + ) + ).json()) as PaginatedResponse; + const roles = paginatedRole.items; + console.log(roles); + + return ( +
+ {roles.map((role) => ( + +
+ role avatar +

{role.name}

+
+

{role.description}

+
+ ))} +
+ ); +}; + +export default RoleGroupPage; diff --git a/src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx b/src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx new file mode 100644 index 0000000000..a681f4f8da --- /dev/null +++ b/src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { buttonVariants } from "@/components/ui/Button"; +import Link from "next/link"; +import { useSelectedLayoutSegment } from "next/navigation"; + +export const RoleGroupNavLink = ({ + tab, +}: { tab: { label: string; path: string; segment: string } }) => { + const layoutSegment = useSelectedLayoutSegment(); + const isActive = tab.segment === layoutSegment; + + return ( + + {tab.label} + + ); +}; diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx new file mode 100644 index 0000000000..940e431d16 --- /dev/null +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -0,0 +1,74 @@ +import { DashboardContainer } from "@/components/DashboardContainer"; +import { Button } from "@/components/ui/Button"; +import { ScrollArea, ScrollBar } from "@/components/ui/ScrollArea"; +import { env } from "@/lib/env"; +import type { + DynamicRoute, + Guild, + PaginatedResponse, + RoleGroup, +} from "@/lib/types"; +import type { PropsWithChildren } from "react"; +import { RoleGroupNavLink } from "./_components/RoleGroupNavLink"; + +const GuildPage = async ({ + params, + children, +}: PropsWithChildren>) => { + const { guildId: guildIdParam } = await params; + const guild = (await ( + await fetch(`${env.NEXT_PUBLIC_API}/guild/urlName/${guildIdParam}`) + ).json()) as Guild; + const paginatedRoleGroup = (await ( + await fetch( + `${env.NEXT_PUBLIC_API}/role-group/search?custumQuery=@guildId:{${guildIdParam}}`, + ) + ).json()) as PaginatedResponse; + const roleGroups = paginatedRoleGroup.items; + + return ( + +
+
+
+
+ avatar +

+ {guild.name} +

+ +
+

+ {guild.description} +

+
+
+ + +
+ {roleGroups.map((rg) => ( + + ))} +
+ +
+ {children} +
+
+ ); +}; + +export default GuildPage; diff --git a/src/app/(dashboard)/[guildId]/page.tsx b/src/app/(dashboard)/[guildId]/page.tsx new file mode 100644 index 0000000000..9ef0175edf --- /dev/null +++ b/src/app/(dashboard)/[guildId]/page.tsx @@ -0,0 +1,3 @@ +const DefaultGuildPage = () => "default guild page"; + +export default DefaultGuildPage; diff --git a/src/app/explorer/components/GuildCard.tsx b/src/app/explorer/components/GuildCard.tsx index cef6659310..5457f1284c 100644 --- a/src/app/explorer/components/GuildCard.tsx +++ b/src/app/explorer/components/GuildCard.tsx @@ -1,6 +1,7 @@ import { Badge } from "@/components/ui/Badge"; import { Card } from "@/components/ui/Card"; import { Skeleton } from "@/components/ui/Skeleton"; +import type { Guild } from "@/lib/types"; import { ImageSquare, Users } from "@phosphor-icons/react/dist/ssr"; import { Avatar, AvatarFallback, AvatarImage } from "@radix-ui/react-avatar"; import Link from "next/link"; diff --git a/src/app/explorer/fetchers.ts b/src/app/explorer/fetchers.ts index f2ce54db18..2157d158a8 100644 --- a/src/app/explorer/fetchers.ts +++ b/src/app/explorer/fetchers.ts @@ -1,4 +1,5 @@ import { env } from "@/lib/env"; +import type { Guild, PaginatedResponse } from "@/lib/types"; import { PAGE_SIZE } from "./constants"; export const getGuildSearch = diff --git a/src/app/explorer/page.tsx b/src/app/explorer/page.tsx index 34803c5bed..e9ac5a8fca 100644 --- a/src/app/explorer/page.tsx +++ b/src/app/explorer/page.tsx @@ -1,6 +1,7 @@ import { AuthBoundary } from "@/components/AuthBoundary"; import { SignInButton } from "@/components/SignInButton"; import { env } from "@/lib/env"; +import type { Guild, PaginatedResponse } from "@/lib/types"; import { HydrationBoundary, QueryClient, diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 3fc5d94a16..0000000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -const Home = () => { - return ( -
-

Hello, Guild!

-

Test, one, two, three...

-
- ); -}; - -export default Home; diff --git a/src/components/DashboardContainer.tsx b/src/components/DashboardContainer.tsx new file mode 100644 index 0000000000..143cdd4dbe --- /dev/null +++ b/src/components/DashboardContainer.tsx @@ -0,0 +1,27 @@ +import { cn } from "@/lib/cssUtils"; +import { Slot } from "@radix-ui/react-slot"; +import type { HTMLAttributes } from "react"; + +interface DashboardContainerProps extends HTMLAttributes { + asChild?: boolean; +} + +export const DashboardContainer = ({ + children, + className, + asChild = false, + ...props +}: DashboardContainerProps) => { + const Comp = asChild ? Slot : "div"; + return ( + + {children} + + ); +}; diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000000..ed901c252e --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,80 @@ +export type PaginatedResponse = { + page: number; + pageSize: number; + sortBy: string; + reverse: boolean; + searchQuery: string; + query: string; + items: Item[]; + total: number; +}; + +export type DynamicRoute> = { + params: T; +}; + +const G = { + id: "8dcc0fc6-31e6-4e6c-b24b-19b5a4f244ca", + createdAt: 1732304836273, + updatedAt: 1732304836273, + name: "Basic Template", + urlName: "basic-template", + description: "This template provides basic functionality for...", + imageUrl: "https://example.com/images/template.jpg", + backgroundImageUrl: "https://example.com/images/background.jpg", + visibility: {}, + settings: {}, + searchTags: [], + categoryTags: [], + socialLinks: {}, +}; + +const RG = { + id: "ff3b37ed-727e-5ab3-a202-32f9e3387e5a", + legacyId: "1024", + createdAt: "1725848548765", + updatedAt: "1725848548765", + name: "#RR", + urlName: "rr", + description: "", + imageUrl: + "https://guild-xyz.mypinata.cloud/ipfs/QmfVFG6mFMtFzNYsKXyN3FffBmpZzrqWcycBgDYjLzg14C", + visibility: { + hideFromGuildPage: false, + }, + settings: { + position: 0, + }, + guildId: "32feb189-9b03-59c8-a1ef-7b296cbc42e6", + type: "CATEGORY", +}; + +const R = { + id: "85afa420-f3d6-5113-a978-1eea9f2ef543", + legacyId: "17184", + createdAt: "1664067944168", + updatedAt: "1677588151210", + system: { + lastSyncedAt: null, + }, + name: '"Loser" Skellie Chimps', + urlName: "loser-skellie-chimps", + description: "hold Loser from Skellie Chimps", + imageUrl: "/guildLogos/213.svg", + visibility: { + hidden: false, + hideFromEyes: false, + }, + settings: { + position: 0, + anyOfNum: 0, + logic: "AND", + }, + guildId: "30c83783-db7e-58b3-b890-3afd77ad8af3", + groupId: "", + members: "0", +}; + +export type Guild = typeof G; +export type RoleGroup = typeof RG; +export type Role = typeof R; From bbf915de44a2832d9c24fc36f22238dc4e399b49 Mon Sep 17 00:00:00 2001 From: Dominik Stumpf Date: Sat, 23 Nov 2024 00:10:09 +0100 Subject: [PATCH 02/93] chore: center join guild button --- src/app/(dashboard)/[guildId]/layout.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx index 940e431d16..ef5b2e976d 100644 --- a/src/app/(dashboard)/[guildId]/layout.tsx +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -30,16 +30,18 @@ const GuildPage = async ({
-
-
- avatar -

- {guild.name} -

+
+
+
+ avatar +

+ {guild.name} +

+
From e6df6f71afbc9a08d82e07a93961cdb5d1ddd343 Mon Sep 17 00:00:00 2001 From: Dominik Stumpf Date: Sat, 23 Nov 2024 02:41:56 +0100 Subject: [PATCH 03/93] feat: add requirement ui --- .../[guildId]/[roleGroupId]/page.tsx | 68 ++++++++++++++----- src/app/(dashboard)/[guildId]/layout.tsx | 4 +- src/app/(dashboard)/[guildId]/page.tsx | 29 +++++++- src/styles/globals.css | 6 +- 4 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx b/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx index c3dd83fec7..c5b6943135 100644 --- a/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx +++ b/src/app/(dashboard)/[guildId]/[roleGroupId]/page.tsx @@ -1,3 +1,4 @@ +import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; import { env } from "@/lib/env"; import type { @@ -7,43 +8,78 @@ import type { Role, RoleGroup, } from "@/lib/types"; +import { Lock } from "@phosphor-icons/react/dist/ssr"; +import { ScrollArea } from "@radix-ui/react-scroll-area"; +import { Fragment } from "react"; const RoleGroupPage = async ({ params, }: DynamicRoute<{ roleGroupId: string; guildId: string }>) => { const { roleGroupId: roleGroupIdParam, guildId: guildIdParam } = await params; - const _guild = (await ( + const guild = (await ( await fetch(`${env.NEXT_PUBLIC_API}/guild/urlName/${guildIdParam}`) ).json()) as Guild; const paginatedRoleGroup = (await ( await fetch( - `${env.NEXT_PUBLIC_API}/role-group/search?custumQuery=@guildId:{${guildIdParam}}`, + `${env.NEXT_PUBLIC_API}/role-group/search?customQuery=@guildId:{${guild.id}}&pageSize=${Number.MAX_SAFE_INTEGER}`, ) ).json()) as PaginatedResponse; const roleGroups = paginatedRoleGroup.items; - const roleGroup = roleGroups.find((rg) => rg.urlName === roleGroupIdParam); - + const roleGroup = roleGroups.find((rg) => rg.urlName === roleGroupIdParam)!; + console.log( + `${env.NEXT_PUBLIC_API}/role/search?customQuery=@guildId:{${guild.id}}&pageSize=${Number.MAX_SAFE_INTEGER}`, + ); const paginatedRole = (await ( await fetch( - `${env.NEXT_PUBLIC_API}/role/search?custumQuery=@guildId:{${guildIdParam}} @roleGroupId:{${roleGroup}}`, + `${env.NEXT_PUBLIC_API}/role/search?customQuery=@guildId:{${guild.id}}&pageSize=${Number.MAX_SAFE_INTEGER}`, ) ).json()) as PaginatedResponse; - const roles = paginatedRole.items; - console.log(roles); + const roles = paginatedRole.items.filter((r) => r.groupId === roleGroup.id); return (
{roles.map((role) => ( - -
- role avatar -

{role.name}

+ +
+
+ role avatar +

{role.name}

+
+

{role.description}

+
+
+
+ + REQUIREMENTS + + +
+ +
+ {Array.from({ length: 16 }, (_, i) => ( + + {i > 0 &&
} +
+
+
+

Requirement name

+

+ description, additional info +

+
+
+ + ))} +
+
-

{role.description}

))}
diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx index ef5b2e976d..9ba26ee1b8 100644 --- a/src/app/(dashboard)/[guildId]/layout.tsx +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -21,7 +21,7 @@ const GuildPage = async ({ ).json()) as Guild; const paginatedRoleGroup = (await ( await fetch( - `${env.NEXT_PUBLIC_API}/role-group/search?custumQuery=@guildId:{${guildIdParam}}`, + `${env.NEXT_PUBLIC_API}/role-group/search?customQuery=@guildId:{${guild.id}}`, ) ).json()) as PaginatedResponse; const roleGroups = paginatedRoleGroup.items; @@ -46,7 +46,7 @@ const GuildPage = async ({ Join Guild
-

+

{guild.description}

diff --git a/src/app/(dashboard)/[guildId]/page.tsx b/src/app/(dashboard)/[guildId]/page.tsx index 9ef0175edf..37adb52139 100644 --- a/src/app/(dashboard)/[guildId]/page.tsx +++ b/src/app/(dashboard)/[guildId]/page.tsx @@ -1,3 +1,30 @@ -const DefaultGuildPage = () => "default guild page"; +import { env } from "@/lib/env"; +import type { + DynamicRoute, + Guild, + PaginatedResponse, + RoleGroup, +} from "@/lib/types"; +import { redirect } from "next/navigation"; + +const DefaultGuildPage = async ({ + params, +}: DynamicRoute<{ guildId: string }>) => { + const { guildId: guildIdParam } = await params; + const guild = (await ( + await fetch(`${env.NEXT_PUBLIC_API}/guild/urlName/${guildIdParam}`) + ).json()) as Guild; + const paginatedRoleGroup = (await ( + await fetch( + `${env.NEXT_PUBLIC_API}/role-group/search?customQuery=@guildId:{${guild.id}}`, + ) + ).json()) as PaginatedResponse; + const roleGroups = paginatedRoleGroup.items; + const roleGroup = roleGroups.at(0); + if (roleGroup) { + redirect(`/${guildIdParam}/${roleGroup.urlName}`); + } + return "default guild page"; +}; export default DefaultGuildPage; diff --git a/src/styles/globals.css b/src/styles/globals.css index 37f0070839..4bf3b317c0 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -83,7 +83,7 @@ html { --image: var(--gray-700); --skeleton: var(--gray-300); --border: var(--gray-300); - + --input-border: var(--gray-200); --input-border-accent: var(--gray-300); --input-border-invalid: var(--red-500); @@ -179,3 +179,7 @@ html { body { @apply bg-background text-foreground font-sans min-h-screen antialiased selection:bg-foreground selection:text-background; } + +* { + border-color: var(--border); +} From 43937103d0c5537bf4b5e6c4569cae30d9ecd797 Mon Sep 17 00:00:00 2001 From: BrickheadJohnny Date: Tue, 26 Nov 2024 15:25:43 +0100 Subject: [PATCH 04/93] fix: remove the `[guild]` directory --- src/app/(dashboard)/[guild]/page.tsx | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/app/(dashboard)/[guild]/page.tsx diff --git a/src/app/(dashboard)/[guild]/page.tsx b/src/app/(dashboard)/[guild]/page.tsx deleted file mode 100644 index b31d944b7e..0000000000 --- a/src/app/(dashboard)/[guild]/page.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { Metadata } from "next"; - -type Props = { - params: Promise<{ guild: string }>; - searchParams: Promise<{ [key: string]: string | string[] | undefined }>; -}; - -export async function generateMetadata({ params }: Props): Promise { - const urlName = (await params).guild; - - return { - title: urlName, - }; -} - -const GuildPage = async ({ params }: Props) => { - const urlName = (await params).guild; - - return ( -
-

Guild page

-

{`URL name: ${urlName}`}

-
- ); -}; - -export default GuildPage; From 008047f5b9e24410154da66d4850b4cd9f2090cc Mon Sep 17 00:00:00 2001 From: BrickheadJohnny Date: Tue, 26 Nov 2024 17:02:07 +0100 Subject: [PATCH 05/93] feat: GuildImage component --- src/app/(dashboard)/[guildId]/layout.tsx | 76 +++++++++---------- .../explorer/components/GuildCard.tsx | 24 ++---- src/components/GuildImage.tsx | 30 ++++++++ 3 files changed, 74 insertions(+), 56 deletions(-) create mode 100644 src/components/GuildImage.tsx diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx index 0d03fcd36c..d87df77ee5 100644 --- a/src/app/(dashboard)/[guildId]/layout.tsx +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -1,4 +1,4 @@ -import { DashboardContainer } from "@/components/DashboardContainer"; +import { GuildImage } from "@/components/GuildImage"; import { Button } from "@/components/ui/Button"; import { ScrollArea, ScrollBar } from "@/components/ui/ScrollArea"; import { env } from "@/lib/env"; @@ -24,49 +24,45 @@ const GuildPage = async ({ const roleGroups = paginatedRoleGroup.items; return ( - -
-
-
-
-
- avatar -

- {guild.name} -

-
- +
+
+
+
+
+ +

+ {guild.name} +

-

- {guild.description} -

+
+

+ {guild.description} +

+
- -
- {roleGroups.map((rg) => ( - - ))} -
- -
- {children} -
- + +
+ {roleGroups.map((rg) => ( + + ))} +
+ +
+ {children} +
); }; diff --git a/src/app/(dashboard)/explorer/components/GuildCard.tsx b/src/app/(dashboard)/explorer/components/GuildCard.tsx index bc19365ba9..c62c7db5f1 100644 --- a/src/app/(dashboard)/explorer/components/GuildCard.tsx +++ b/src/app/(dashboard)/explorer/components/GuildCard.tsx @@ -1,9 +1,10 @@ +import { GuildImage } from "@/components/GuildImage"; import { Badge } from "@/components/ui/Badge"; import { Card } from "@/components/ui/Card"; import { Skeleton } from "@/components/ui/Skeleton"; import type { Guild } from "@/lib/schemas/guild"; -import { ImageSquare, Users } from "@phosphor-icons/react/dist/ssr"; -import { Avatar, AvatarFallback, AvatarImage } from "@radix-ui/react-avatar"; +import { Users } from "@phosphor-icons/react/dist/ssr"; + import Link from "next/link"; import type { FunctionComponent } from "react"; @@ -14,20 +15,11 @@ export const GuildCard: FunctionComponent<{ guild: Guild }> = ({ guild }) => { className="relative rounded-2xl outline-none focus-visible:ring-4" > - - - - - - +

{guild.name} diff --git a/src/components/GuildImage.tsx b/src/components/GuildImage.tsx new file mode 100644 index 0000000000..3ee8f5e1d3 --- /dev/null +++ b/src/components/GuildImage.tsx @@ -0,0 +1,30 @@ +import { cn } from "@/lib/cssUtils"; +import type { Guild } from "@/lib/schemas/guild"; +import { ImageSquare } from "@phosphor-icons/react/dist/ssr"; +import { Avatar, AvatarFallback, AvatarImage } from "@radix-ui/react-avatar"; + +type Props = { + className?: string; + name: Guild["name"]; + imageUrl: Guild["imageUrl"]; +}; + +export const GuildImage = ({ name, imageUrl, className }: Props) => ( + + + + + + +); From 70da86d38c27a0ad12feba0d2ce3c2c598753ebc Mon Sep 17 00:00:00 2001 From: BrickheadJohnny Date: Wed, 27 Nov 2024 08:44:41 +0100 Subject: [PATCH 06/93] cleanup: remove playground and rename the components folder --- .../RoleGroupNavLink.tsx | 0 src/app/(dashboard)/[guildId]/layout.tsx | 2 +- src/app/playground/page.tsx | 19 ------------------- 3 files changed, 1 insertion(+), 20 deletions(-) rename src/app/(dashboard)/[guildId]/{_components => components}/RoleGroupNavLink.tsx (100%) delete mode 100644 src/app/playground/page.tsx diff --git a/src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx b/src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx similarity index 100% rename from src/app/(dashboard)/[guildId]/_components/RoleGroupNavLink.tsx rename to src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx index d87df77ee5..39398852ea 100644 --- a/src/app/(dashboard)/[guildId]/layout.tsx +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -6,7 +6,7 @@ import type { Guild } from "@/lib/schemas/guild"; import type { RoleGroup } from "@/lib/schemas/roleGroup"; import type { DynamicRoute, PaginatedResponse } from "@/lib/types"; import type { PropsWithChildren } from "react"; -import { RoleGroupNavLink } from "./_components/RoleGroupNavLink"; +import { RoleGroupNavLink } from "./components/RoleGroupNavLink"; const GuildPage = async ({ params, diff --git a/src/app/playground/page.tsx b/src/app/playground/page.tsx deleted file mode 100644 index 9bf4132b81..0000000000 --- a/src/app/playground/page.tsx +++ /dev/null @@ -1,19 +0,0 @@ -const Playground = () => { - return ( -
-

- Hello, Guild!, page for testing frameworks, configs -

-

Hello, Guild!

-

Test, one, two, three...

-

- Test, one, two, three... -

-

- In dark mode I appear violet, in light we go rose -

-
- ); -}; - -export default Playground; From 87c34e21ff235b253b125b26d13cc0b715e99254 Mon Sep 17 00:00:00 2001 From: BrickheadJohnny Date: Wed, 27 Nov 2024 09:25:33 +0100 Subject: [PATCH 07/93] feat: role group navigation menu --- .../[guildId]/components/RoleGroupNavLink.tsx | 55 +++++++++++++------ src/app/(dashboard)/[guildId]/layout.tsx | 38 +++++++++---- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx b/src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx index a681f4f8da..851ee253a7 100644 --- a/src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx +++ b/src/app/(dashboard)/[guildId]/components/RoleGroupNavLink.tsx @@ -1,25 +1,48 @@ "use client"; -import { buttonVariants } from "@/components/ui/Button"; +import { + Button, + type ButtonProps, + buttonVariants, +} from "@/components/ui/Button"; +import { Card } from "@/components/ui/Card"; import Link from "next/link"; -import { useSelectedLayoutSegment } from "next/navigation"; +import { usePathname } from "next/navigation"; +import type { PropsWithChildren } from "react"; export const RoleGroupNavLink = ({ - tab, -}: { tab: { label: string; path: string; segment: string } }) => { - const layoutSegment = useSelectedLayoutSegment(); - const isActive = tab.segment === layoutSegment; + href, + children, +}: PropsWithChildren<{ href: string }>) => { + const pathname = usePathname(); + const isActive = pathname === href; return ( - - {tab.label} - + + + {children} + + ); }; + +export const RoleGroupNavButton = ({ + children, + leftIcon, + className, +}: PropsWithChildren>) => ( + + + +); diff --git a/src/app/(dashboard)/[guildId]/layout.tsx b/src/app/(dashboard)/[guildId]/layout.tsx index 39398852ea..758545452c 100644 --- a/src/app/(dashboard)/[guildId]/layout.tsx +++ b/src/app/(dashboard)/[guildId]/layout.tsx @@ -5,8 +5,12 @@ import { env } from "@/lib/env"; import type { Guild } from "@/lib/schemas/guild"; import type { RoleGroup } from "@/lib/schemas/roleGroup"; import type { DynamicRoute, PaginatedResponse } from "@/lib/types"; +import { Plus } from "@phosphor-icons/react/dist/ssr"; import type { PropsWithChildren } from "react"; -import { RoleGroupNavLink } from "./components/RoleGroupNavLink"; +import { + RoleGroupNavButton, + RoleGroupNavLink, +} from "./components/RoleGroupNavLink"; const GuildPage = async ({ params, @@ -25,7 +29,7 @@ const GuildPage = async ({ return (
-
+
@@ -38,7 +42,9 @@ const GuildPage = async ({ {guild.name}

- +

{guild.description} @@ -46,20 +52,28 @@ const GuildPage = async ({

- -
+ +
+ Home {roleGroups.map((rg) => ( + href={`/${guildIdParam}/${rg.urlName}`} + > + {rg.name} + ))} + }> + Create page +
- +
{children}
From 8ef76fabca43a2bda5187b4fdaee7ec80bbef4b8 Mon Sep 17 00:00:00 2001 From: BrickheadJohnny Date: Wed, 27 Nov 2024 11:13:55 +0100 Subject: [PATCH 08/93] feat: simple create page form --- .../[guildId]/components/CreateRoleGroup.tsx | 166 ++++++++++++++++++ .../[guildId]/components/RoleGroupNavLink.tsx | 20 +-- src/app/(dashboard)/[guildId]/layout.tsx | 11 +- src/components/ImageUploader.tsx | 4 +- src/components/ui/Drawer.tsx | 2 +- src/components/ui/Form.tsx | 2 + src/components/ui/ResponsiveDialog.tsx | 10 +- src/lib/schemas/roleGroup.ts | 3 +- 8 files changed, 186 insertions(+), 32 deletions(-) create mode 100644 src/app/(dashboard)/[guildId]/components/CreateRoleGroup.tsx diff --git a/src/app/(dashboard)/[guildId]/components/CreateRoleGroup.tsx b/src/app/(dashboard)/[guildId]/components/CreateRoleGroup.tsx new file mode 100644 index 0000000000..7330ea9104 --- /dev/null +++ b/src/app/(dashboard)/[guildId]/components/CreateRoleGroup.tsx @@ -0,0 +1,166 @@ +"use client"; + +import { ImageUploader } from "@/components/ImageUploader"; +import { Button } from "@/components/ui/Button"; +import { Card } from "@/components/ui/Card"; +import { + FormControl, + FormErrorMessage, + FormField, + FormItem, + FormLabel, +} from "@/components/ui/Form"; +import { Input } from "@/components/ui/Input"; +import { Label } from "@/components/ui/Label"; +import { + ResponsiveDialog, + ResponsiveDialogBody, + ResponsiveDialogContent, + ResponsiveDialogFooter, + ResponsiveDialogHeader, + ResponsiveDialogTitle, + ResponsiveDialogTrigger, +} from "@/components/ui/ResponsiveDialog"; +import { Textarea } from "@/components/ui/Textarea"; +import { GUILD_AUTH_COOKIE_NAME } from "@/config/constants"; +import { env } from "@/lib/env"; +import { fetcher } from "@/lib/fetcher"; +import { getCookie } from "@/lib/getCookie"; +import { + type CreateRoleGroupForm, + CreateRoleGroupSchema, + type RoleGroup, +} from "@/lib/schemas/roleGroup"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { CheckCircle, Plus, XCircle } from "@phosphor-icons/react/dist/ssr"; +import { useMutation } from "@tanstack/react-query"; +import { FormProvider, useForm } from "react-hook-form"; +import { toast } from "sonner"; + +type Props = { + guildId: string; +}; + +export const CreateRoleGroup = ({ guildId }: Props) => ( + + + + + + + + + + Create page + + + + + +); + +const CreateRoleGroupDialogForm = ({ guildId }: Props) => { + const form = useForm({ + mode: "onTouched", + resolver: zodResolver(CreateRoleGroupSchema), + defaultValues: { + guildId, + imageUrl: "", + name: "", + description: "", + }, + }); + + const { mutate: onSubmit, isPending } = useMutation({ + mutationFn: async (data: CreateRoleGroupForm) => { + const token = getCookie(GUILD_AUTH_COOKIE_NAME); + + if (!token) throw new Error("Unauthorized"); // TODO: custom errors? + + return fetcher(`${env.NEXT_PUBLIC_API}/role-group`, { + method: "POST", + headers: { + "X-Auth-Token": token, + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + }, + onError: (error) => { + // TODO: parse the error and display it in a user-friendly way + toast("An error occurred", { + icon: , + }); + console.error(error); + }, + onSuccess: (res) => { + console.log("RESPONSE", res); + toast("Page successfully created", { + description: "You're being redirected to it", + icon: , + }); + // router.push(`/${res.urlName}`); + }, + }); + + console.log(form); + + return ( + + +
+
+ +
+ form.setValue("imageUrl", imageUrl)} + /> +
+ ( + + + + + + + )} + /> +
+ + ( + + Description + +