From: Muhammad Rizki <[email protected]>
To: Ammar Faizi <[email protected]>
Cc: Muhammad Rizki <[email protected]>,
Alviro Iskandar Setiawan <[email protected]>,
GNU/Weeb Mailing List <[email protected]>
Subject: [PATCH v1 06/17] fix(breadcrumb): Move settingsNav to settings items navigations
Date: Wed, 5 Mar 2025 21:40:05 +0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
Move settingsNav items to navigations settings items to make breadcrumb
works properly.
Signed-off-by: Muhammad Rizki <[email protected]>
---
| 39 +++++++++++++++----
src/lib/constants/navigations.ts | 31 +++++++--------
src/lib/typings/common.d.ts | 1 +
src/lib/utilities/index.ts | 3 +-
src/lib/utilities/navigation.ts | 5 +++
| 3 +-
.../(protected)/settings/+layout.svelte | 5 +--
src/routes/(protected)/settings/+page.ts | 6 ++-
8 files changed, 63 insertions(+), 30 deletions(-)
create mode 100644 src/lib/utilities/navigation.ts
--git a/src/lib/components/customs/header.svelte b/src/lib/components/customs/header.svelte
index 44c681e..6a343d5 100644
--- a/src/lib/components/customs/header.svelte
+++ b/src/lib/components/customs/header.svelte
@@ -4,12 +4,28 @@
import { page } from "$app/state";
import { navigations } from "$constants";
import Separator from "$components/ui/separator/separator.svelte";
+ import * as typing from "$typings";
- const getRouteName = () => {
- const pathname = page.url.pathname;
- const found = navigations.find((path) => path.url === pathname);
+ const getParentRoute = (
+ path: string,
+ items: typing.Navigations[],
+ routePath: typing.Navigations[] = []
+ ): typing.Navigations[] => {
+ for (const item of items) {
+ if (path === item.url) {
+ return [...routePath, item];
+ }
- return found?.name ?? "";
+ if (item.items) {
+ const foundPath = getParentRoute(path, item.items, [...routePath, item]);
+ if (foundPath.length) return foundPath;
+ }
+ }
+ return [];
+ };
+
+ const getRouteName = () => {
+ return getParentRoute(page.url.pathname, navigations);
};
</script>
@@ -23,9 +39,18 @@
<Breadcrumb.Link href="/">G/W Mail</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
- <Breadcrumb.Item class="select-none">
- <Breadcrumb.Page>{getRouteName()}</Breadcrumb.Page>
- </Breadcrumb.Item>
+ {#each getRouteName() as route, index (route.url)}
+ {#if index === getRouteName().length - 1}
+ <Breadcrumb.Item class="select-none">
+ <Breadcrumb.Page>{route.name}</Breadcrumb.Page>
+ </Breadcrumb.Item>
+ {:else}
+ <Breadcrumb.Item class="hidden md:block">
+ <Breadcrumb.Link href={route.url}>{route.name}</Breadcrumb.Link>
+ </Breadcrumb.Item>
+ <Breadcrumb.Separator />
+ {/if}
+ {/each}
</Breadcrumb.List>
</Breadcrumb.Root>
</div>
diff --git a/src/lib/constants/navigations.ts b/src/lib/constants/navigations.ts
index ca5e77b..4266930 100644
--- a/src/lib/constants/navigations.ts
+++ b/src/lib/constants/navigations.ts
@@ -1,6 +1,6 @@
import * as typing from "$typings";
-import Home from "lucide-svelte/icons/home"
-import Settings from "lucide-svelte/icons/settings"
+import Home from "lucide-svelte/icons/home";
+import Settings from "lucide-svelte/icons/settings";
export const navigations: typing.Navigations[] = [
{
@@ -11,19 +11,18 @@ export const navigations: typing.Navigations[] = [
{
name: "Settings",
icon: Settings,
- url: "/settings"
+ url: "/settings",
+ items: [
+ {
+ name: "Profile",
+ description: "Manage your profile.",
+ url: "/settings/profile"
+ },
+ {
+ name: "Account",
+ description: "Manage your account credentials.",
+ url: "/settings/account"
+ }
+ ]
}
] as const;
-
-export const settingsNav: typing.Navigations[] = [
- {
- name: "Profile",
- description: "Manage your profile.",
- url: "/settings/profile"
- },
- {
- name: "Account",
- description: "Manage your account credentials.",
- url: "/settings/account"
- }
-];
diff --git a/src/lib/typings/common.d.ts b/src/lib/typings/common.d.ts
index cdbe0d4..1f4a795 100644
--- a/src/lib/typings/common.d.ts
+++ b/src/lib/typings/common.d.ts
@@ -8,6 +8,7 @@ export interface Navigations {
icon?: typeof IconType;
url: string;
disabled?: boolean;
+ items?: Navigations[]
}
export interface LabelAndValue {
diff --git a/src/lib/utilities/index.ts b/src/lib/utilities/index.ts
index ed0291d..48c622d 100644
--- a/src/lib/utilities/index.ts
+++ b/src/lib/utilities/index.ts
@@ -1,3 +1,4 @@
+import { getSettingsNav } from "./navigation";
import { cn } from "./styling";
-export { cn };
+export { cn, getSettingsNav };
diff --git a/src/lib/utilities/navigation.ts b/src/lib/utilities/navigation.ts
new file mode 100644
index 0000000..4b84eca
--- /dev/null
+++ b/src/lib/utilities/navigation.ts
@@ -0,0 +1,5 @@
+import { navigations } from "$constants";
+
+export const getSettingsNav = () => {
+ return navigations.find((nav) => nav.url.includes("/settings"))?.items ?? [];
+};
--git a/src/routes/(protected)/settings/(components)/settings-header.svelte b/src/routes/(protected)/settings/(components)/settings-header.svelte
index cc13950..34e5900 100644
--- a/src/routes/(protected)/settings/(components)/settings-header.svelte
+++ b/src/routes/(protected)/settings/(components)/settings-header.svelte
@@ -1,8 +1,9 @@
<script lang="ts">
import { page } from "$app/state";
- import { settingsNav } from "$constants/navigations";
import Separator from "$components/ui/separator/separator.svelte";
+ import { getSettingsNav } from "$utils";
+ const settingsNav = getSettingsNav();
const activeNav = $derived(settingsNav.find((e) => page.url.pathname === e.url));
</script>
diff --git a/src/routes/(protected)/settings/+layout.svelte b/src/routes/(protected)/settings/+layout.svelte
index 71e30d8..80d306a 100644
--- a/src/routes/(protected)/settings/+layout.svelte
+++ b/src/routes/(protected)/settings/+layout.svelte
@@ -1,9 +1,8 @@
<script lang="ts">
import { Separator } from "$lib/components/ui/separator";
-
- import { settingsNav } from "$constants/navigations";
import SettingsNavigation from "./(components)/settings-nav.svelte";
import SettingsHeader from "./(components)/settings-header.svelte";
+ import { getSettingsNav } from "$utils";
let { children } = $props();
</script>
@@ -16,7 +15,7 @@
<Separator class="my-6" />
<div class="flex flex-col space-y-8 xl:flex-row xl:space-x-8 xl:space-y-0">
<aside class="xl:w-[12%]">
- <SettingsNavigation items={settingsNav} />
+ <SettingsNavigation items={getSettingsNav()} />
</aside>
<div class="flex-1">
<div class="space-y-6">
diff --git a/src/routes/(protected)/settings/+page.ts b/src/routes/(protected)/settings/+page.ts
index 3c846ad..c29023a 100644
--- a/src/routes/(protected)/settings/+page.ts
+++ b/src/routes/(protected)/settings/+page.ts
@@ -1,11 +1,13 @@
import { redirect } from "@sveltejs/kit";
import type { PageLoad } from "./$types";
-import { settingsNav } from "$constants/navigations";
+import { getSettingsNav } from "$utils";
export const load: PageLoad = async () => {
// get first page that are not disabled.
+ const settingsNav = getSettingsNav();
const firstPage = settingsNav.find((e) => !e.disabled);
+ const url = firstPage?.items?.[0].url ?? firstPage?.url;
// if it don't exist, redirect to index page.
- return redirect(307, firstPage?.url ?? "/");
+ return redirect(307, url ?? "/settings/profile");
};
--
Muhammad Rizki
next prev parent reply other threads:[~2025-03-05 14:40 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-05 14:39 [PATCH v1 00/17] Profile Page, SEO, Fixed API structure, Docs Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 01/17] fix(typing): add user_info type prop Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 02/17] refactor: optimize icon imports to reduce bundle size Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 03/17] chore(change-pwd): adjust change password heading styling Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 04/17] chore(settings/layout): use prose: for " Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 05/17] fix(profile): fix edit avatar button position Muhammad Rizki
2025-03-05 14:40 ` Muhammad Rizki [this message]
2025-03-05 14:40 ` [PATCH v1 07/17] chore(responsive): adjust styling Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 08/17] chore(navigations): Replace index /settings url Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 09/17] feat(ui): Add popover and dialog UI component Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 10/17] feat(http): Use PUBLIC_BASE_URL for each environment Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 11/17] feat(icons): Add social icons Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 12/17] feat(typing/enum): add Gender and IsActive enum Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 13/17] refactor!:feat: update API response structure, update profile page Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 14/17] chore(meta): rename favicon.png to favicon.ico Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 15/17] feat(seo): add SEO for site metadata Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 16/17] chore(login): use $derived() instead of function based Muhammad Rizki
2025-03-05 14:40 ` [PATCH v1 17/17] docs: update README.md Muhammad Rizki
2025-03-05 16:54 ` [PATCH v1 00/17] Profile Page, SEO, Fixed API structure, Docs Ammar Faizi
2025-03-05 16:57 ` Alviro Iskandar Setiawan
2025-03-06 7:01 ` Muhammad Rizki
2025-03-06 7:02 ` Alviro Iskandar Setiawan
2025-03-06 7:04 ` Muhammad Rizki
2025-03-06 2:02 ` Muhammad Rizki
2025-03-06 3:37 ` Ammar Faizi
2025-03-05 17:04 ` Ammar Faizi
2025-03-05 18:14 ` Alviro Iskandar Setiawan
2025-03-06 1:59 ` Muhammad Rizki
2025-03-06 3:35 ` Ammar Faizi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox