mertani-web-toolkit 0.1.17 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,8 @@ Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.c
4
4
 
5
5
  Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
6
 
7
+ 📘 **Documentation:** [storybook.mertani.com](https://storybook.mertani.com/)
8
+
7
9
  ## Creating a project
8
10
 
9
11
  If you're seeing this, you've probably already done this step. Congrats!
@@ -0,0 +1,59 @@
1
+
2
+ <script lang="ts">
3
+ type PresetDirection = 'down' | 'up' | 'left' | 'right';
4
+
5
+ const {
6
+ width = 12,
7
+ height = 8,
8
+ direction = 'down'
9
+ } = $props<{
10
+ width?: number | string;
11
+ height?: number | string;
12
+ direction?: PresetDirection | number | string;
13
+ }>();
14
+
15
+ const presets: Record<PresetDirection, string> = {
16
+ down: 'rotate(0deg)',
17
+ up: 'rotate(180deg)',
18
+ left: 'rotate(90deg)',
19
+ right: 'rotate(-90deg)'
20
+ };
21
+
22
+ function normalizeRotation(value: PresetDirection | number | string): string {
23
+ if (typeof value === 'string') {
24
+ const trimmed = value.trim().toLowerCase();
25
+ if (trimmed in presets) {
26
+ return presets[trimmed as PresetDirection];
27
+ }
28
+ if (/^-?\d+(\.\d+)?(deg|rad|turn)?$/.test(trimmed)) {
29
+ // Append deg if unit missing
30
+ const unit = /deg|rad|turn$/.test(trimmed) ? '' : 'deg';
31
+ return `rotate(${trimmed}${unit})`;
32
+ }
33
+ }
34
+
35
+ if (typeof value === 'number' && Number.isFinite(value)) {
36
+ return `rotate(${value}deg)`;
37
+ }
38
+
39
+ return presets.down;
40
+ }
41
+
42
+ const transform = $derived(normalizeRotation(direction));
43
+ </script>
44
+
45
+ <svg
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ {width}
48
+ {height}
49
+ viewBox="0 0 12 8"
50
+ fill="currentColor"
51
+ style={`transform: ${transform}; transform-origin: center; transition: transform 0.2s ease;`}
52
+ >
53
+ <path
54
+ fill-rule="evenodd"
55
+ clip-rule="evenodd"
56
+ d="M0.4403 1.06506C0.48094 1.02431 0.529218 0.991987 0.58237 0.969932C0.635522 0.947876 0.692503 0.936523 0.75005 0.936523C0.807596 0.936523 0.864577 0.947876 0.917729 0.969932C0.970881 0.991987 1.01916 1.02431 1.0598 1.06506L6.00005 6.00618L10.9403 1.06506C10.981 1.02438 11.0293 0.992112 11.0824 0.970097C11.1356 0.948083 11.1925 0.936752 11.25 0.936752C11.3076 0.936752 11.3645 0.948083 11.4177 0.970097C11.4708 0.992112 11.5191 1.02438 11.5598 1.06506C11.6005 1.10573 11.6327 1.15402 11.6548 1.20717C11.6768 1.26032 11.6881 1.31728 11.6881 1.37481C11.6881 1.43233 11.6768 1.48929 11.6548 1.54244C11.6327 1.59559 11.6005 1.64388 11.5598 1.68456L6.3098 6.93456C6.26916 6.9753 6.22088 7.00762 6.16773 7.02968C6.11458 7.05173 6.0576 7.06309 6.00005 7.06309C5.9425 7.06309 5.88552 7.05173 5.83237 7.02968C5.77922 7.00762 5.73094 6.9753 5.6903 6.93456L0.4403 1.68456C0.399557 1.64392 0.367232 1.59564 0.345176 1.54248C0.323121 1.48933 0.311768 1.43235 0.311768 1.37481C0.311768 1.31726 0.323121 1.26028 0.345176 1.20713C0.367232 1.15397 0.399557 1.1057 0.4403 1.06506Z"
57
+ fill="currentColor"
58
+ />
59
+ </svg>
@@ -0,0 +1,9 @@
1
+ type PresetDirection = 'down' | 'up' | 'left' | 'right';
2
+ type $$ComponentProps = {
3
+ width?: number | string;
4
+ height?: number | string;
5
+ direction?: PresetDirection | number | string;
6
+ };
7
+ declare const ChevronDown: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type ChevronDown = ReturnType<typeof ChevronDown>;
9
+ export default ChevronDown;
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ const { width = 16, height = 17, color = '#212529' } = $props();
3
+ </script>
4
+
5
+ <svg {width} {height} viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <g clip-path="url(#clip0_6267_47931)">
7
+ <rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />
8
+ <path
9
+ d="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"
10
+ fill={color}
11
+ />
12
+ </g>
13
+ <defs>
14
+ <clipPath id="clip0_6267_47931">
15
+ <rect width="16" height="16" fill="white" transform="translate(0 0.5)" />
16
+ </clipPath>
17
+ </defs>
18
+ </svg>
@@ -0,0 +1,7 @@
1
+ declare const GearTwo: import("svelte").Component<{
2
+ width?: number;
3
+ height?: number;
4
+ color?: string;
5
+ }, {}, "">;
6
+ type GearTwo = ReturnType<typeof GearTwo>;
7
+ export default GearTwo;
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M6 14H3.33333C2.97971 14 2.64057 13.8595 2.39052 13.6095C2.14048 13.3594 2 13.0203 2 12.6667V3.33333C2 2.97971 2.14048 2.64057 2.39052 2.39052C2.64057 2.14048 2.97971 2 3.33333 2H6M10.6667 11.3333L14 8M14 8L10.6667 4.66667M14 8H6" stroke="#3F4047" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,26 @@
1
+ export default Logout;
2
+ type Logout = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Logout: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -0,0 +1,11 @@
1
+ <svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_2167_105141)">
3
+ <rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01"/>
4
+ <path d="M8 8.49902C8.79565 8.49902 9.55871 8.18295 10.1213 7.62034C10.6839 7.05773 11 6.29467 11 5.49902C11 4.70337 10.6839 3.94031 10.1213 3.3777C9.55871 2.81509 8.79565 2.49902 8 2.49902C7.20435 2.49902 6.44129 2.81509 5.87868 3.3777C5.31607 3.94031 5 4.70337 5 5.49902C5 6.29467 5.31607 7.05773 5.87868 7.62034C6.44129 8.18295 7.20435 8.49902 8 8.49902ZM10 5.49902C10 6.02946 9.78929 6.53816 9.41421 6.91324C9.03914 7.28831 8.53043 7.49902 8 7.49902C7.46957 7.49902 6.96086 7.28831 6.58579 6.91324C6.21071 6.53816 6 6.02946 6 5.49902C6 4.96859 6.21071 4.45988 6.58579 4.08481C6.96086 3.70974 7.46957 3.49902 8 3.49902C8.53043 3.49902 9.03914 3.70974 9.41421 4.08481C9.78929 4.45988 10 4.96859 10 5.49902ZM14 13.499C14 14.499 13 14.499 13 14.499H3C3 14.499 2 14.499 2 13.499C2 12.499 3 9.49902 8 9.49902C13 9.49902 14 12.499 14 13.499ZM13 13.495C12.999 13.249 12.846 12.509 12.168 11.831C11.516 11.179 10.289 10.499 8 10.499C5.71 10.499 4.484 11.179 3.832 11.831C3.154 12.509 3.002 13.249 3 13.495H13Z" fill="#212529"/>
5
+ </g>
6
+ <defs>
7
+ <clipPath id="clip0_2167_105141">
8
+ <rect width="16" height="16" fill="white" transform="translate(0 0.5)"/>
9
+ </clipPath>
10
+ </defs>
11
+ </svg>
@@ -0,0 +1,26 @@
1
+ export default User;
2
+ type User = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const User: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -0,0 +1,10 @@
1
+ <script>
2
+ const { width = 16, height = 16, color = '#000', rotate = false } = $props();
3
+ </script>
4
+
5
+ <svg {width} {height} style={rotate ? 'transform: rotate(180deg)' : ''} viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <path
7
+ d="M16.5 3C16.5 1.89543 15.6046 1 14.5 1H2.5C1.39543 1 0.5 1.89543 0.5 3V13C0.5 14.1046 1.39543 15 2.5 15H14.5C15.6046 15 16.5 14.1046 16.5 13V3ZM11.5 2V14H2.5C1.94771 14 1.5 13.5523 1.5 13V3C1.5 2.44772 1.94772 2 2.5 2H11.5ZM12.5 2H14.5C15.0523 2 15.5 2.44772 15.5 3V13C15.5 13.5523 15.0523 14 14.5 14H12.5V2Z"
8
+ fill={color}
9
+ />
10
+ </svg>
@@ -0,0 +1,17 @@
1
+ export default Window;
2
+ type Window = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const Window: import("svelte").Component<{
7
+ width?: number;
8
+ height?: number;
9
+ color?: string;
10
+ rotate?: boolean;
11
+ }, {}, "">;
12
+ type $$ComponentProps = {
13
+ width?: number;
14
+ height?: number;
15
+ color?: string;
16
+ rotate?: boolean;
17
+ };
@@ -0,0 +1,3 @@
1
+ @import 'tailwindcss';
2
+ @import 'tailwindcss/theme';
3
+ @import 'tailwindcss/utilities';
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import './IMSLayout@1.css';
3
+ import ImsHeader from './components/ImsHeader.svelte';
4
+ import ImsSidebar from './components/ImsSidebar.svelte';
5
+ import type { IImsLayout } from './types/IImsLayout.js';
6
+
7
+ const { children, appName, header, sidebar, pageInfo }: IImsLayout = $props();
8
+
9
+ let showSidebar = $state(true);
10
+
11
+ function onToggleSidebar() {
12
+ showSidebar = !showSidebar;
13
+ }
14
+ </script>
15
+
16
+ <svelte:head>
17
+ <title>{appName}</title>
18
+ </svelte:head>
19
+
20
+ <div class="flex h-screen flex-col bg-[#F5F5F5]">
21
+ <div class="flex flex-1 overflow-hidden">
22
+ <ImsSidebar bind:show={showSidebar} {pageInfo} sidebar={sidebar || {}} />
23
+ <main class="flex-1 overflow-auto bg-[#f6f8fa]">
24
+ <ImsHeader {showSidebar} version={header?.version} {onToggleSidebar} />
25
+ </main>
26
+ {@render children?.()}
27
+ </div>
28
+ </div>
29
+
30
+ <style>
31
+ </style>
@@ -0,0 +1,5 @@
1
+ import './IMSLayout@1.css';
2
+ import type { IImsLayout } from './types/IImsLayout.js';
3
+ declare const IMSLayout1: import("svelte").Component<IImsLayout, {}, "">;
4
+ type IMSLayout1 = ReturnType<typeof IMSLayout1>;
5
+ export default IMSLayout1;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import Window from '../../../../icons/Window.svelte';
3
+
4
+ const {
5
+ version = 'v1.0.0',
6
+ showSidebar,
7
+ onToggleSidebar
8
+ } = $props<{ version?: string; showSidebar: boolean; onToggleSidebar: () => void }>();
9
+ </script>
10
+
11
+ <header
12
+ class="sticky top-0 z-20 flex h-[60px] items-center justify-between border-b border-[#e0e0e0] bg-white p-4"
13
+ >
14
+ <button
15
+ type="button"
16
+ title="Toggle sidebar"
17
+ onclick={onToggleSidebar}
18
+ class="grid h-10 w-10 place-items-center rounded-lg border border-transparent text-[#495057] transition hover:border-[#e0e0e0] hover:bg-[#f5f5f5]"
19
+ >
20
+ <Window color={'currentColor'} width={20} height={20} rotate={showSidebar ? true : false} />
21
+ </button>
22
+ <span class="text-sm font-medium">Versi {version}</span>
23
+ </header>
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ version?: string;
3
+ showSidebar: boolean;
4
+ onToggleSidebar: () => void;
5
+ };
6
+ declare const ImsHeader: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type ImsHeader = ReturnType<typeof ImsHeader>;
8
+ export default ImsHeader;
@@ -0,0 +1,335 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import { goto } from '$app/navigation';
4
+ import { page } from '$app/state';
5
+ import ChevronDown from '../../../../icons/ChevronDown.svelte';
6
+ import GearTwo from '../../../../icons/GearTwo.svelte';
7
+ import User from '../../../../icons/User.svelte';
8
+ import Logout from '../../../../icons/Logout.svelte';
9
+ import type { ISidebarData } from '../types/IImsLayout.js';
10
+ import { USER_ROLE_ADMIN, UserStore } from '../../../../stores/UserStore.js';
11
+ import { deleteCookie, USER_TOKEN } from '../../../../utils/Cookie.js';
12
+
13
+ const {
14
+ show = $bindable(true),
15
+ pageInfo,
16
+ sidebar
17
+ } = $props<{ show?: boolean; pageInfo: any; sidebar: ISidebarData }>();
18
+
19
+ let selectedDropdownId = $state(pageInfo.namespace || sidebar.dropdownData?.[0]?.id);
20
+ let areaDropdownOpen = $state(false);
21
+ let userMenuOpen = $state(false);
22
+ let openGroups = $state<Record<string, boolean>>({});
23
+
24
+ let dropdownRef: HTMLDivElement | undefined;
25
+ const user = sidebar.user ?? { name: '', role: '', initials: '' };
26
+ const isAdmin = user?.role === USER_ROLE_ADMIN;
27
+
28
+ const navItems = $derived(sidebar.nav ?? []);
29
+ const selectedDropdownLabel = $derived(
30
+ sidebar.dropdownData?.find((item: any) => item.id === selectedDropdownId)?.name ?? ''
31
+ );
32
+
33
+ onMount(() => {
34
+ const handleDocumentClick = (event: MouseEvent) => {
35
+ if (!dropdownRef) return;
36
+ const target = event.target as Node | null;
37
+ if (!target || dropdownRef.contains(target)) return;
38
+ areaDropdownOpen = false;
39
+ };
40
+
41
+ document.addEventListener('click', handleDocumentClick);
42
+ return () => document.removeEventListener('click', handleDocumentClick);
43
+ });
44
+
45
+ function toggleAreaDropdown() {
46
+ areaDropdownOpen = !areaDropdownOpen;
47
+ }
48
+
49
+ function closeAreaDropdown() {
50
+ areaDropdownOpen = false;
51
+ }
52
+
53
+ function toggleUserMenu() {
54
+ userMenuOpen = !userMenuOpen;
55
+ }
56
+
57
+ function handleLogout() {
58
+ toggleUserMenu();
59
+ UserStore.set(null);
60
+ deleteCookie(USER_TOKEN);
61
+ sessionStorage.removeItem('organization_detail');
62
+ goto('/');
63
+ }
64
+
65
+ function handleProfileClick() {
66
+ goto('/user/profile');
67
+ }
68
+
69
+ function selectArea(areaId: string) {
70
+ selectedDropdownId = areaId;
71
+ closeAreaDropdown();
72
+
73
+ // Split the current pathname and find if any segment matches an area id
74
+ const pathSegments = page.url.pathname.split('/').filter(Boolean);
75
+ const areaIndex = pathSegments.findIndex((segment) =>
76
+ sidebar.dropdownData?.some((item: any) => item.id === segment)
77
+ );
78
+
79
+ if (areaIndex !== -1) {
80
+ // Replace the matched area id with the newly selected areaId
81
+ pathSegments[areaIndex] = areaId;
82
+ const newPath = '/' + pathSegments.join('/');
83
+ goto(newPath);
84
+ }
85
+ }
86
+
87
+ function gotoSlug(slug: string) {
88
+ if (!slug) return;
89
+ const segments = page.url.pathname.split('/').filter(Boolean);
90
+ const areaIndex = segments.findIndex((segment) =>
91
+ sidebar.dropdownData?.some((item: any) => item.id === segment)
92
+ );
93
+ const baseSegments = areaIndex !== -1 ? segments.slice(0, areaIndex + 1) : segments;
94
+ const targetPath = '/' + [...baseSegments, slug].join('/');
95
+ if (targetPath !== page.url.pathname) {
96
+ goto(targetPath);
97
+ }
98
+ }
99
+
100
+ function handleAreaButtonKeydown(event: KeyboardEvent) {
101
+ if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
102
+ event.preventDefault();
103
+ if (!areaDropdownOpen) {
104
+ areaDropdownOpen = true;
105
+ }
106
+ }
107
+ if (event.key === 'Escape') {
108
+ event.preventDefault();
109
+ closeAreaDropdown();
110
+ }
111
+ }
112
+
113
+ function toggleGroup(title: string) {
114
+ openGroups = { ...openGroups, [title]: !openGroups[title] };
115
+ }
116
+
117
+ $effect(() => {
118
+ if (typeof window === 'undefined') {
119
+ return;
120
+ }
121
+
122
+ const pathname = page.url.pathname;
123
+ const items = navItems;
124
+ if (!items.length) {
125
+ return;
126
+ }
127
+
128
+ const hasMatch = items.some((item: any) => {
129
+ if (item.children && item.children.length) {
130
+ return item.children.some((child: any) => pathname.split('/').includes(child.slug));
131
+ }
132
+ return pathname.split('/').includes(item.slug);
133
+ });
134
+ if (hasMatch) {
135
+ return;
136
+ }
137
+
138
+ const fallbackItem = items[0];
139
+ const targetSlug = fallbackItem.children?.[0]?.slug ?? fallbackItem.slug;
140
+
141
+ //TODO: buat dinamis untuk White list path
142
+ const pathSegments = pathname.split('/');
143
+ if (pathSegments.includes('kelola-sub-daerah-irigasi')) {
144
+ if (sidebar?.user?.role === USER_ROLE_ADMIN) {
145
+ return;
146
+ } else {
147
+ goto('/404');
148
+ return;
149
+ }
150
+ }
151
+ if (targetSlug && !pathSegments.includes(targetSlug)) {
152
+ gotoSlug(targetSlug);
153
+ }
154
+ });
155
+
156
+ $effect(() => {
157
+ if (!show) {
158
+ areaDropdownOpen = false;
159
+ userMenuOpen = false;
160
+ }
161
+ });
162
+ </script>
163
+
164
+ <aside
165
+ class={`shrink-0 overflow-visible border-r border-[#e0e0e0] bg-white transition-all duration-200 ease-in-out ${
166
+ show ? 'w-[250px]' : 'w-0'
167
+ }`}
168
+ >
169
+ <div class="flex h-full flex-col bg-white">
170
+ <div class="flex h-[60px] items-center border-b border-[#EAECF0] px-4 py-2.5">
171
+ <img src={sidebar.logoUrl} alt={'Logo'} class="h-10 w-10 object-contain" />
172
+ </div>
173
+
174
+ <div class="flex flex-col gap-1 border-b border-[#EAECF0] px-4 py-4" bind:this={dropdownRef}>
175
+ <div class="text-sm font-medium text-[#2C2C30]">
176
+ {sidebar.dropdownLabel || 'Pilih Sub Daerah Irigasi'}
177
+ </div>
178
+ <div class="flex items-center rounded-sm border border-[#CED4DA]">
179
+ {#if show}
180
+ <div class="relative flex-1">
181
+ <button
182
+ type="button"
183
+ class="flex w-full items-center justify-between rounded-sm bg-white p-2 text-left text-sm text-[#2C2C30]"
184
+ onclick={toggleAreaDropdown}
185
+ onkeydown={handleAreaButtonKeydown}
186
+ >
187
+ <span class="truncate">{selectedDropdownLabel || 'Pilih'}</span>
188
+ <ChevronDown direction={areaDropdownOpen ? 'up' : 'down'} />
189
+ </button>
190
+ {#if areaDropdownOpen}
191
+ <div
192
+ class="absolute top-full right-0 left-0 z-20 mt-2 overflow-hidden rounded-md bg-white shadow-lg"
193
+ >
194
+ <div class="max-h-56 overflow-y-auto py-1">
195
+ {#if sidebar.dropdownData.length}
196
+ {#each sidebar.dropdownData as area}
197
+ <button
198
+ type="button"
199
+ class={`flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-xs transition ${
200
+ area.id === selectedDropdownId
201
+ ? 'text-[#F79B09]'
202
+ : 'text-[#212529] hover:bg-[#F5F5F5]'
203
+ }`}
204
+ onclick={() => selectArea(area.id)}
205
+ >
206
+ <span class="truncate">{area.name}</span>
207
+ </button>
208
+ {/each}
209
+ {:else}
210
+ <div class="px-3 py-2 text-xs text-slate-400">Tidak ada hasil</div>
211
+ {/if}
212
+ </div>
213
+ </div>
214
+ {/if}
215
+ </div>
216
+ {/if}
217
+ {#if isAdmin}
218
+ <button
219
+ type="button"
220
+ onclick={() => gotoSlug('kelola-sub-daerah-irigasi')}
221
+ class="flex size-9 items-center justify-center rounded-r-sm border-l border-[#CED4DA] bg-[#E9ECEF] text-[#2C2C30]"
222
+ >
223
+ <GearTwo />
224
+ </button>
225
+ {/if}
226
+ </div>
227
+ </div>
228
+
229
+ <nav class="flex flex-1 flex-col gap-2 overflow-y-auto p-4">
230
+ {#each sidebar.nav as item}
231
+ <div>
232
+ {#if item.children?.length}
233
+ <button
234
+ type="button"
235
+ class="flex w-full items-center justify-between gap-2 rounded-md px-2.5 py-2 text-left text-[14px] text-[#2C2C30] transition hover:bg-[#F5F5F5]"
236
+ onclick={() => toggleGroup(item.title)}
237
+ >
238
+ <span class="flex items-center gap-2">
239
+ {#if item.icon}
240
+ <span class="text-[#495057]">{@html item.icon}</span>
241
+ {/if}
242
+ <span>{item.title}</span>
243
+ </span>
244
+ <ChevronDown direction={openGroups[item.title] ? 'up' : 'down'} />
245
+ </button>
246
+ {#if openGroups[item.title]}
247
+ <div class="mt-1 ml-6 flex flex-col gap-1">
248
+ {#each item.children as child}
249
+ <button
250
+ onclick={() => gotoSlug(child.slug)}
251
+ class={`flex items-center gap-2 rounded-md px-2.5 py-2 text-[14px] text-[#2C2C30] transition hover:bg-[#F5F5F5] ${page.url.pathname.split('/').includes(child.slug) ? 'bg-[#FFF2C6]' : ''}`}
252
+ >
253
+ {#if child.icon}
254
+ <span class="text-[#495057]">{@html child.icon}</span>
255
+ {/if}
256
+ <span class="text-left">{child.title}</span>
257
+ </button>
258
+ {/each}
259
+ </div>
260
+ {/if}
261
+ {:else}
262
+ <button
263
+ onclick={() => gotoSlug(item.slug)}
264
+ class={`flex w-full items-center justify-between gap-2 rounded-md px-2.5 py-2 text-[14px] text-[#2C2C30] transition hover:bg-[#F5F5F5] ${page.url.pathname.split('/').includes(item.slug) ? 'bg-[#FFF2C6]' : ''}`}
265
+ >
266
+ <span class="flex items-center gap-2">
267
+ {#if item.icon}
268
+ <span class="text-[#495057]">{@html item.icon}</span>
269
+ {/if}
270
+ <span>{item.title}</span>
271
+ </span>
272
+ </button>
273
+ {/if}
274
+ </div>
275
+ {/each}
276
+ </nav>
277
+
278
+ <div class="relative border-t border-[#EAECF0] p-4">
279
+ <button
280
+ type="button"
281
+ class="flex w-full items-center gap-2 text-left"
282
+ onclick={toggleUserMenu}
283
+ >
284
+ <div class="grid size-9 place-items-center">
285
+ <img src={user.avatarUrl} alt="avatar" class="size-full rounded-full object-cover" />
286
+ </div>
287
+ <div class="min-w-0 flex-1">
288
+ <div class="truncate text-[12px] font-medium text-[#495057]">{user.name}</div>
289
+ <div class="truncate text-[10px] text-[#ADB5BD]">{user.role}</div>
290
+ </div>
291
+ <ChevronDown direction={'right'} />
292
+ </button>
293
+ {#if userMenuOpen}
294
+ <div
295
+ class="absolute bottom-0 left-[calc(100%+12px)] z-30 w-[216px] rounded-xl border border-[#EAECF0] bg-white p-4 text-left shadow-[0px_12px_32px_rgba(15,23,42,0.12)]"
296
+ >
297
+ <div class="flex flex-col gap-3">
298
+ <!-- <div>
299
+ <div class="text-xs font-semibold text-[#2C2C30]">Ubah Role</div>
300
+ <div class="mt-2">
301
+ <select
302
+ class="w-full rounded-md border border-[#CED4DA] bg-white px-3 py-2 text-xs text-[#2C2C30] focus:outline-none focus:ring-2 focus:ring-[#F79B09]/40"
303
+ >
304
+ </select>
305
+ </div>
306
+ <div class="mt-1 text-[10px] text-[#ADB5BD]">Lihat view dari role lainnya</div>
307
+ </div>
308
+
309
+ <hr class="border-[#EAECF0]" /> -->
310
+
311
+ <button
312
+ type="button"
313
+ class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs font-medium text-[#2C2C30] transition hover:bg-[#F5F5F5]"
314
+ onclick={handleProfileClick}
315
+ >
316
+ <User />
317
+ <span>Profil Akun</span>
318
+ </button>
319
+
320
+ <button
321
+ type="button"
322
+ class="flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-xs font-semibold text-[#D14343] transition hover:bg-[#FFF5F0]"
323
+ onclick={handleLogout}
324
+ >
325
+ <span>Keluar / Log Out</span>
326
+ <span class="flex items-center gap-1 text-[#D14343]">
327
+ <Logout />
328
+ </span>
329
+ </button>
330
+ </div>
331
+ </div>
332
+ {/if}
333
+ </div>
334
+ </div>
335
+ </aside>
@@ -0,0 +1,9 @@
1
+ import type { ISidebarData } from '../types/IImsLayout.js';
2
+ type $$ComponentProps = {
3
+ show?: boolean;
4
+ pageInfo: any;
5
+ sidebar: ISidebarData;
6
+ };
7
+ declare const ImsSidebar: import("svelte").Component<$$ComponentProps, {}, "show">;
8
+ type ImsSidebar = ReturnType<typeof ImsSidebar>;
9
+ export default ImsSidebar;
@@ -0,0 +1,47 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface IImsLayoutHeader {
3
+ title?: string;
4
+ version?: string;
5
+ }
6
+ export interface ISidebarDropdown {
7
+ id: string;
8
+ name: string;
9
+ }
10
+ export interface ISidebarNavChild {
11
+ title: string;
12
+ slug: string;
13
+ icon?: string;
14
+ widget?: string;
15
+ }
16
+ export interface ISidebarNavItem {
17
+ title: string;
18
+ slug?: string;
19
+ icon?: string;
20
+ children?: ISidebarNavChild[];
21
+ }
22
+ export interface ISidebarUser {
23
+ name?: string;
24
+ role?: string;
25
+ avatarUrl?: string;
26
+ roleOptions?: Array<unknown>;
27
+ }
28
+ export interface ISidebarData {
29
+ logoUrl?: string;
30
+ dropdownLabel?: string;
31
+ dropdownData?: ISidebarDropdown[];
32
+ nav?: ISidebarNavItem[];
33
+ user?: ISidebarUser;
34
+ }
35
+ export interface IImsLayout {
36
+ type: string;
37
+ appName?: string;
38
+ header?: IImsLayoutHeader;
39
+ sidebar?: ISidebarData;
40
+ children?: Snippet;
41
+ pageInfo: {
42
+ type: string;
43
+ organization: string;
44
+ namespace: string;
45
+ pageLvl1: string;
46
+ };
47
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ export declare const IImsLayout: {
2
+ appName: string;
3
+ header: {
4
+ title: string;
5
+ version: string;
6
+ };
7
+ sidebar: {
8
+ logoUrl: string;
9
+ nav: ({
10
+ icon: string;
11
+ slug: string;
12
+ title: string;
13
+ children?: undefined;
14
+ } | {
15
+ children: {
16
+ icon: string;
17
+ slug: string;
18
+ title: string;
19
+ }[];
20
+ icon: string;
21
+ title: string;
22
+ slug?: undefined;
23
+ })[];
24
+ user: {
25
+ avatarUrl: string;
26
+ name: string;
27
+ role: string;
28
+ };
29
+ dropdownData: {
30
+ id: string;
31
+ name: string;
32
+ }[];
33
+ };
34
+ pageInfo: {
35
+ type: string;
36
+ organization: string;
37
+ namespace: string;
38
+ pageLvl1: string;
39
+ pageLvl2: string;
40
+ };
41
+ type: string;
42
+ };
@@ -0,0 +1,98 @@
1
+ export const IImsLayout = {
2
+ appName: 'Saddang Irrigation Monitoring System',
3
+ header: {
4
+ title: 'Saddang Irrigation Monitoring System',
5
+ version: '1.2.0'
6
+ },
7
+ sidebar: {
8
+ logoUrl: '/assets/images/logo.png',
9
+ nav: [
10
+ {
11
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
12
+ slug: 'beranda',
13
+ title: 'Beranda'
14
+ },
15
+ {
16
+ children: [
17
+ {
18
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
19
+ slug: 'profil-daerah-irigasi',
20
+ title: 'Profil Daerah Irigasi'
21
+ },
22
+ {
23
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
24
+ slug: 'infrastruktur-irigasi',
25
+ title: 'Infrastruktur Irigasi'
26
+ },
27
+ {
28
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
29
+ slug: 'skema-jaringan-irigasi',
30
+ title: 'Skema Jaringan Irigasi'
31
+ }
32
+ ],
33
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
34
+ title: 'Daerah Irigasi'
35
+ },
36
+ {
37
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
38
+ slug: 'debit-klimatologi',
39
+ title: 'Debit & Klimatologi'
40
+ },
41
+ {
42
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
43
+ slug: 'rencana-pola-tanam',
44
+ title: 'Rencana Pola Tanam'
45
+ },
46
+ {
47
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
48
+ slug: 'laporan',
49
+ title: 'Laporan'
50
+ },
51
+ {
52
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
53
+ slug: 'monitoring',
54
+ title: 'Monitoring'
55
+ },
56
+ {
57
+ icon: '<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">\n\t<g clip-path="url(#clip0_6267_47931)">\n\t\t<rect width="16" height="16" transform="translate(0 0.5)" fill="white" fill-opacity="0.01" />\n\t\t<path\n\t\t\td="M11.4194 1.5C11.5956 1.50006 11.7689 1.54723 11.9213 1.63574C12.0736 1.7242 12.2001 1.85099 12.2875 2.00391L15.7162 8.00391C15.8025 8.15491 15.848 8.3261 15.8481 8.5C15.8481 8.67397 15.8025 8.84503 15.7162 8.99609L12.2875 14.9961C12.2001 15.1491 12.0738 15.2767 11.9213 15.3652C11.7689 15.4537 11.5956 15.4999 11.4194 15.5H4.57953C4.40331 15.4999 4.22997 15.4537 4.07758 15.3652C3.92519 15.2767 3.79877 15.1491 3.71136 14.9961L0.28363 8.99609C0.197374 8.84505 0.151794 8.67394 0.151794 8.5C0.15183 8.3261 0.197373 8.15491 0.28363 8.00391L3.71136 2.00391C3.79872 1.85101 3.92533 1.72422 4.07758 1.63574C4.22997 1.54725 4.40331 1.50008 4.57953 1.5H11.4194ZM4.57953 2.5L1.15179 8.5L4.57953 14.5H11.4194L14.8481 8.5L11.4194 2.5H4.57953ZM7.6264 5.07422C8.08711 5.01559 8.55481 5.04987 9.00238 5.17383C9.45007 5.29785 9.86888 5.50944 10.2338 5.79688C10.5988 6.0844 10.9029 6.44234 11.1284 6.84863C11.5851 7.65204 11.7055 8.60324 11.4633 9.49512C11.2212 10.387 10.6367 11.1473 9.83636 11.6094C9.03607 12.0714 8.08526 12.198 7.19183 11.9619C6.29844 11.7257 5.53526 11.1458 5.06781 10.3486C4.82861 9.95028 4.67052 9.50771 4.60394 9.04785C4.5374 8.58808 4.56376 8.11968 4.68011 7.66992C4.7965 7.22008 5.0014 6.7976 5.28265 6.42773C5.56383 6.05806 5.91561 5.74791 6.31781 5.51562C6.72019 5.28326 7.16547 5.13294 7.6264 5.07422ZM8.73871 6.19336C8.10166 6.02041 7.42195 6.10738 6.84808 6.43359C6.56147 6.59655 6.30985 6.81463 6.10785 7.0752C5.90593 7.33569 5.75673 7.63311 5.67035 7.95117C5.58397 8.26934 5.56145 8.60178 5.60394 8.92871C5.64644 9.25566 5.75354 9.57092 5.9184 9.85645C6.08325 10.142 6.30298 10.3925 6.56488 10.5928C6.82672 10.7929 7.12613 10.9392 7.44476 11.0234C7.76338 11.1076 8.09579 11.1277 8.4223 11.083C8.74882 11.0383 9.06377 10.9304 9.34808 10.7637C9.91754 10.4298 10.3317 9.88331 10.5004 9.24512C10.669 8.60701 10.5785 7.92804 10.2485 7.35645C9.91843 6.7848 9.37571 6.36637 8.73871 6.19336Z"\n\t\t\tfill="#212529"\n\t\t/>\n\t</g>\n\t<defs>\n\t\t<clipPath id="clip0_6267_47931">\n\t\t\t<rect width="16" height="16" fill="white" transform="translate(0 0.5)" />\n\t\t</clipPath>\n\t</defs>\n</svg>',
58
+ slug: 'pengaturan',
59
+ title: 'Pengaturan'
60
+ }
61
+ ],
62
+ user: {
63
+ avatarUrl: 'https://storage.mertani.my.id/user-photo-10ca5eb5-5e49-45bc-abc4-59c99657a859',
64
+ name: 'You rooot',
65
+ role: 'admin-mertani'
66
+ },
67
+ dropdownData: [
68
+ {
69
+ id: '1efbafdf-f83f-42ba-a710-29f875598895',
70
+ name: 'pekkaabata'
71
+ },
72
+ {
73
+ id: 'addf69ef-3b04-4847-8e38-4755bb208242',
74
+ name: 'test 40'
75
+ },
76
+ {
77
+ id: 'd98e6173-fd7b-46fb-a0f9-c27c5cffdf6e',
78
+ name: 'Namespace v1.2 zzzz'
79
+ },
80
+ {
81
+ id: 'bf3974aa-f898-48d0-a890-09dce1d98e70',
82
+ name: 'test 5'
83
+ },
84
+ {
85
+ id: '5fa1932e-dbca-442d-b06b-a675c5f390bd',
86
+ name: 'Saddang'
87
+ }
88
+ ]
89
+ },
90
+ pageInfo: {
91
+ type: 'dashboard',
92
+ organization: 'ims-saddang',
93
+ namespace: '5fa1932e-dbca-442d-b06b-a675c5f390bd',
94
+ pageLvl1: 'infrastruktur-irigasi',
95
+ pageLvl2: 'detail-saluran_af91ba98-05ed-47f2-aeab-8d44293768c5'
96
+ },
97
+ type: 'ims-layout@1'
98
+ };
@@ -0,0 +1,7 @@
1
+ import type { User } from '../types/UserModel.js';
2
+ export interface UserStoreModel {
3
+ user: User;
4
+ organizationIdx: number;
5
+ }
6
+ export declare const UserStore: import("svelte/store").Writable<UserStoreModel | null>;
7
+ export declare const USER_ROLE_ADMIN = "admin-mertani";
@@ -0,0 +1,3 @@
1
+ import { writable } from 'svelte/store';
2
+ export const UserStore = writable(null);
3
+ export const USER_ROLE_ADMIN = 'admin-mertani';
@@ -0,0 +1,14 @@
1
+ export interface User {
2
+ address: string;
3
+ created_at: string;
4
+ email: string;
5
+ is_blocked: boolean;
6
+ is_verified: boolean;
7
+ name: string;
8
+ organization_ids: string[];
9
+ phone_number: string;
10
+ photo: string;
11
+ role: string;
12
+ updated_at: string;
13
+ user_id: string;
14
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export declare const USER_TOKEN = "user-token";
2
+ export declare function setCookie(name: string, value: unknown, d: Date): void;
3
+ export declare function getCookie(name: string): string;
4
+ export declare function deleteCookie(name: string): void;
@@ -0,0 +1,21 @@
1
+ export const USER_TOKEN = 'user-token';
2
+ export function setCookie(name, value, d) {
3
+ const expires = `expires=${d.toUTCString()}`;
4
+ document.cookie = `${name}=${value}; ${expires}; path=/;Lax`;
5
+ }
6
+ export function getCookie(name) {
7
+ const nameEq = `${name}=`;
8
+ const cookies = document.cookie.split(';');
9
+ for (let c of cookies) {
10
+ while (c.charAt(0) === ' ')
11
+ c = c.substring(1);
12
+ if (c.indexOf(nameEq) === 0)
13
+ return c.substring(nameEq.length, c.length);
14
+ }
15
+ return '';
16
+ }
17
+ export function deleteCookie(name) {
18
+ const d = new Date();
19
+ d.setTime(d.getTime() + -1 * 24 * 60 * 60 * 1000);
20
+ setCookie(name, '', d);
21
+ }
package/package.json CHANGED
@@ -1,75 +1,76 @@
1
- {
2
- "name": "mertani-web-toolkit",
3
- "version": "0.1.17",
4
- "scripts": {
5
- "dev": "vite dev",
6
- "build": "vite build && npm run prepack",
7
- "preview": "vite preview",
8
- "prepare": "svelte-kit sync || echo ''",
9
- "prepack": "svelte-kit sync && svelte-package && publint",
10
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12
- "format": "prettier --write .",
13
- "lint": "prettier --check . && eslint .",
14
- "test:e2e": "playwright test",
15
- "test": "npm run test:e2e",
16
- "storybook": "storybook dev -p 6006",
17
- "build-storybook": "storybook build"
18
- },
19
- "files": [
20
- "dist",
21
- "!dist/**/*.test.*",
22
- "!dist/**/*.spec.*"
23
- ],
24
- "sideEffects": [
25
- "**/*.css"
26
- ],
27
- "svelte": "./dist/index.js",
28
- "types": "./dist/index.d.ts",
29
- "type": "module",
30
- "exports": {
31
- ".": {
32
- "types": "./dist/index.d.ts",
33
- "svelte": "./dist/index.js"
34
- }
35
- },
36
- "peerDependencies": {
37
- "svelte": "^5.0.0"
38
- },
39
- "devDependencies": {
40
- "@chromatic-com/storybook": "^4.1.1",
41
- "@eslint/compat": "^1.2.5",
42
- "@eslint/js": "^9.22.0",
43
- "@playwright/test": "^1.49.1",
44
- "@storybook/addon-a11y": "^9.1.8",
45
- "@storybook/addon-docs": "^9.1.8",
46
- "@storybook/addon-svelte-csf": "^5.0.8",
47
- "@storybook/addon-vitest": "^9.1.8",
48
- "@storybook/sveltekit": "^9.1.8",
49
- "@sveltejs/adapter-auto": "^6.0.0",
50
- "@sveltejs/kit": "^2.22.0",
51
- "@sveltejs/package": "^2.0.0",
52
- "@sveltejs/vite-plugin-svelte": "^6.0.0",
53
- "@tailwindcss/vite": "^4.0.0",
54
- "@types/node": "^22",
55
- "eslint": "^9.22.0",
56
- "eslint-config-prettier": "^10.0.1",
57
- "eslint-plugin-storybook": "^9.1.8",
58
- "eslint-plugin-svelte": "^3.0.0",
59
- "globals": "^16.0.0",
60
- "prettier": "^3.4.2",
61
- "prettier-plugin-svelte": "^3.3.3",
62
- "prettier-plugin-tailwindcss": "^0.6.11",
63
- "publint": "^0.3.2",
64
- "storybook": "^9.1.8",
65
- "svelte": "^5.0.0",
66
- "svelte-check": "^4.0.0",
67
- "tailwindcss": "^4.0.0",
68
- "typescript": "^5.0.0",
69
- "typescript-eslint": "^8.20.0",
70
- "vite": "^7.0.4"
71
- },
72
- "keywords": [
73
- "svelte"
74
- ]
75
- }
1
+ {
2
+ "name": "mertani-web-toolkit",
3
+ "version": "0.1.18",
4
+ "homepage": "https://storybook.mertani.com/",
5
+ "scripts": {
6
+ "dev": "vite dev",
7
+ "build": "vite build && npm run prepack",
8
+ "preview": "vite preview",
9
+ "prepare": "svelte-kit sync || echo ''",
10
+ "prepack": "svelte-kit sync && svelte-package && publint",
11
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
13
+ "format": "prettier --write .",
14
+ "lint": "prettier --check . && eslint .",
15
+ "test:e2e": "playwright test",
16
+ "test": "npm run test:e2e",
17
+ "storybook": "storybook dev -p 6006",
18
+ "build-storybook": "storybook build"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "!dist/**/*.test.*",
23
+ "!dist/**/*.spec.*"
24
+ ],
25
+ "sideEffects": [
26
+ "**/*.css"
27
+ ],
28
+ "svelte": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "type": "module",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "svelte": "./dist/index.js"
35
+ }
36
+ },
37
+ "peerDependencies": {
38
+ "svelte": "^5.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@chromatic-com/storybook": "^4.1.1",
42
+ "@eslint/compat": "^1.2.5",
43
+ "@eslint/js": "^9.22.0",
44
+ "@playwright/test": "^1.49.1",
45
+ "@storybook/addon-a11y": "^9.1.8",
46
+ "@storybook/addon-docs": "^9.1.8",
47
+ "@storybook/addon-svelte-csf": "^5.0.8",
48
+ "@storybook/addon-vitest": "^9.1.8",
49
+ "@storybook/sveltekit": "^9.1.8",
50
+ "@sveltejs/adapter-auto": "^6.0.0",
51
+ "@sveltejs/kit": "^2.22.0",
52
+ "@sveltejs/package": "^2.0.0",
53
+ "@sveltejs/vite-plugin-svelte": "^6.0.0",
54
+ "@tailwindcss/vite": "^4.0.0",
55
+ "@types/node": "^22",
56
+ "eslint": "^9.22.0",
57
+ "eslint-config-prettier": "^10.0.1",
58
+ "eslint-plugin-storybook": "^9.1.8",
59
+ "eslint-plugin-svelte": "^3.0.0",
60
+ "globals": "^16.0.0",
61
+ "prettier": "^3.4.2",
62
+ "prettier-plugin-svelte": "^3.3.3",
63
+ "prettier-plugin-tailwindcss": "^0.6.11",
64
+ "publint": "^0.3.2",
65
+ "storybook": "^9.1.8",
66
+ "svelte": "^5.0.0",
67
+ "svelte-check": "^4.0.0",
68
+ "tailwindcss": "^4.0.0",
69
+ "typescript": "^5.0.0",
70
+ "typescript-eslint": "^8.20.0",
71
+ "vite": "^7.0.4"
72
+ },
73
+ "keywords": [
74
+ "svelte"
75
+ ]
76
+ }