From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server-vie001.gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_DBL_BLOCKED_OPENDNS, URIBL_ZEN_BLOCKED_OPENDNS autolearn=ham autolearn_force=no version=3.4.6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1740264901; bh=7xdWXxSEUVaQ5Bv/b+O1rGUj7M4W8JDSK8jLAApgOoI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Message-ID:Date:From: Reply-To:Subject:To:Cc:In-Reply-To:References:Resent-Date: Resent-From:Resent-To:Resent-Cc:User-Agent:Content-Type: Content-Transfer-Encoding; b=ibhQrfT6hJf+KEhr9sWwjxs0qmKbkuw0+qnXDdxttxdw4eODb7W/s+OrU75/dRLEo TsI9oHK7SBjFTvtBOxZM3NlqBHyBTU8LHS/IGX3Jd1+PmGk52GN9RkKL8BeJjCVgzk iTC+pD1IIUR8jDkAKzeFIsS3OH1krmfB71HjlimFzph6h6nygPlxfuWIDs4ZmFMX3K /55wjtYTGtL07uS2xhRpvumrA/RnvdbbiSLtYTIk03fGHrJRIn7O8Or2UhGvlHZIY5 cfs9N9xmsWpQ+0/pundadcScL2jBa0UsCqJEAszw7NjynVwRBSjw7q1WU100BTzXZe ZwcSZcqdRFnmA== Received: from localhost.localdomain (unknown [101.128.125.35]) by server-vie001.gnuweeb.org (Postfix) with ESMTPSA id 64A9520744CC; Sat, 22 Feb 2025 22:55:00 +0000 (UTC) From: Muhammad Rizki To: Ammar Faizi Cc: Muhammad Rizki , Alviro Iskandar Setiawan , GNU/Weeb Mailing List Subject: [PATCH v1 13/13] feat: add settings pages Date: Sun, 23 Feb 2025 05:54:19 +0700 Message-ID: <20250222225423.1377-14-kiizuha@gnuweeb.org> X-Mailer: git-send-email 2.45.2.windows.1 In-Reply-To: <20250222225423.1377-1-kiizuha@gnuweeb.org> References: <20250222225423.1377-1-kiizuha@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This commit adds profile management page and account management page, including its schemas and local UI components. Signed-off-by: Muhammad Rizki --- src/lib/schemas/account-schema.ts | 12 ++ src/lib/schemas/profile-schema.ts | 8 + .../(components)/settings-header.svelte | 13 ++ .../settings/(components)/settings-nav.svelte | 45 +++++ .../(protected)/settings/+layout.svelte | 28 +++ src/routes/(protected)/settings/+page.ts | 11 ++ .../(protected)/settings/account/+page.svelte | 107 +++++++++++ .../(protected)/settings/account/+page.ts | 9 + .../(protected)/settings/profile/+page.svelte | 170 ++++++++++++++++++ .../(protected)/settings/profile/+page.ts | 20 +++ 10 files changed, 423 insertions(+) create mode 100644 src/lib/schemas/account-schema.ts create mode 100644 src/lib/schemas/profile-schema.ts create mode 100644 src/routes/(protected)/settings/(components)/settings-header.svelte create mode 100644 src/routes/(protected)/settings/(components)/settings-nav.svelte create mode 100644 src/routes/(protected)/settings/+layout.svelte create mode 100644 src/routes/(protected)/settings/+page.ts create mode 100644 src/routes/(protected)/settings/account/+page.svelte create mode 100644 src/routes/(protected)/settings/account/+page.ts create mode 100644 src/routes/(protected)/settings/profile/+page.svelte create mode 100644 src/routes/(protected)/settings/profile/+page.ts diff --git a/src/lib/schemas/account-schema.ts b/src/lib/schemas/account-schema.ts new file mode 100644 index 0000000..d633405 --- /dev/null +++ b/src/lib/schemas/account-schema.ts @@ -0,0 +1,12 @@ +import { z } from "zod"; + +export const accountSchema = z + .object({ + cur_pass: z.string(), + new_pass: z.string(), + retype_new_pass: z.string() + }) + .refine(({ new_pass, retype_new_pass }) => new_pass === retype_new_pass, { + message: "The new password does not match with the retyped one.", + path: ["retype_new_pass"] + }); diff --git a/src/lib/schemas/profile-schema.ts b/src/lib/schemas/profile-schema.ts new file mode 100644 index 0000000..fa67c17 --- /dev/null +++ b/src/lib/schemas/profile-schema.ts @@ -0,0 +1,8 @@ +import { z } from "zod"; + +export const profileSchema = z.object({ + avatar: z.instanceof(File).optional(), + username: z.string().optional(), + full_name: z.string().optional(), + gender: z.string().optional() +}); diff --git a/src/routes/(protected)/settings/(components)/settings-header.svelte b/src/routes/(protected)/settings/(components)/settings-header.svelte new file mode 100644 index 0000000..cc13950 --- /dev/null +++ b/src/routes/(protected)/settings/(components)/settings-header.svelte @@ -0,0 +1,13 @@ + + +
+

{activeNav?.name}

+

{activeNav?.description}

+
+ diff --git a/src/routes/(protected)/settings/(components)/settings-nav.svelte b/src/routes/(protected)/settings/(components)/settings-nav.svelte new file mode 100644 index 0000000..1ff5968 --- /dev/null +++ b/src/routes/(protected)/settings/(components)/settings-nav.svelte @@ -0,0 +1,45 @@ + + + diff --git a/src/routes/(protected)/settings/+layout.svelte b/src/routes/(protected)/settings/+layout.svelte new file mode 100644 index 0000000..3ef02e4 --- /dev/null +++ b/src/routes/(protected)/settings/+layout.svelte @@ -0,0 +1,28 @@ + + +
+
+

Settings

+

Manage your account settings and set e-mail preferences.

+
+ +
+ +
+
+ + {@render children()} +
+
+
+
diff --git a/src/routes/(protected)/settings/+page.ts b/src/routes/(protected)/settings/+page.ts new file mode 100644 index 0000000..3c846ad --- /dev/null +++ b/src/routes/(protected)/settings/+page.ts @@ -0,0 +1,11 @@ +import { redirect } from "@sveltejs/kit"; +import type { PageLoad } from "./$types"; +import { settingsNav } from "$constants/navigations"; + +export const load: PageLoad = async () => { + // get first page that are not disabled. + const firstPage = settingsNav.find((e) => !e.disabled); + + // if it don't exist, redirect to index page. + return redirect(307, firstPage?.url ?? "/"); +}; diff --git a/src/routes/(protected)/settings/account/+page.svelte b/src/routes/(protected)/settings/account/+page.svelte new file mode 100644 index 0000000..00590bf --- /dev/null +++ b/src/routes/(protected)/settings/account/+page.svelte @@ -0,0 +1,107 @@ + + +
+ + + {#snippet children({ props })} + Current Password + + + {/snippet} + + + + + + {#snippet children({ props })} + New Password + + + {/snippet} + + + + + + {#snippet children({ props })} + Re-type New Password + + + {/snippet} + + + + +
diff --git a/src/routes/(protected)/settings/account/+page.ts b/src/routes/(protected)/settings/account/+page.ts new file mode 100644 index 0000000..8089d3e --- /dev/null +++ b/src/routes/(protected)/settings/account/+page.ts @@ -0,0 +1,9 @@ +import type { PageLoad } from "./$types"; +import { zod } from "sveltekit-superforms/adapters"; +import { superValidate } from "sveltekit-superforms"; +import { accountSchema } from "$lib/schemas/account-schema"; + +export const load: PageLoad = async () => { + const form = await superValidate(zod(accountSchema)); + return { form }; +}; diff --git a/src/routes/(protected)/settings/profile/+page.svelte b/src/routes/(protected)/settings/profile/+page.svelte new file mode 100644 index 0000000..442e271 --- /dev/null +++ b/src/routes/(protected)/settings/profile/+page.svelte @@ -0,0 +1,170 @@ + + +
+
+ + + {#snippet children({ props })} + + + + {getShortName()} + +
+ + Edit +
+
+ + {/snippet} +
+
+
+ +
+ + + {#snippet children({ props })} + Username + + This is your GNU/Weeb email username. + {/snippet} + + + + + + {#snippet children({ props })} + Full Name + + {/snippet} + + + + + + {#snippet children({ props })} + Gender + +
+ + +
+
+ + +
+
+ {/snippet} +
+
+
+ + +
diff --git a/src/routes/(protected)/settings/profile/+page.ts b/src/routes/(protected)/settings/profile/+page.ts new file mode 100644 index 0000000..9e036c8 --- /dev/null +++ b/src/routes/(protected)/settings/profile/+page.ts @@ -0,0 +1,20 @@ +import type { PageLoad } from "./$types"; +import { zod } from "sveltekit-superforms/adapters"; +import { superValidate } from "sveltekit-superforms"; +import { profileSchema } from "$lib/schemas/profile-schema"; +import { useAuth } from "$lib/hooks/auth.svelte"; + +export const load: PageLoad = async () => { + const auth = useAuth(); + auth.refresh(); + + const data = { + username: auth.user?.username, + full_name: auth.user?.full_name, + gender: auth.user?.gender + }; + + const form = await superValidate(data, zod(profileSchema)); + + return { form }; +}; -- Muhammad Rizki