rune-lab 0.0.1 → 0.0.2-alpha-2

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.
@@ -1,115 +1,88 @@
1
1
  <!-- src/lib/components/layout/Footer.svelte -->
2
2
  <script lang="ts">
3
3
  import { appData } from '../../stores/app.svelte.js';
4
+ import { footerStore } from '../../stores/layout/footer.svelte.js';
4
5
 
5
- // Define footer section types
6
- interface FooterLink {
7
- text: string;
8
- href: string;
9
- }
10
-
11
- interface FooterSection {
12
- title: string;
13
- links: FooterLink[];
14
- }
15
-
16
- // Footer sections configuration
17
- const footerSections: FooterSection[] = [
18
- {
19
- title: "Product",
20
- links: [
21
- { text: "Features", href: "/features" },
22
- { text: "Docs", href: "/docs" },
23
- { text: "API", href: "/api" },
24
- { text: "Pricing", href: "/pricing" }
25
- ]
26
- },
27
- {
28
- title: "Company",
29
- links: [
30
- { text: "About", href: "/about" },
31
- { text: "Blog", href: "/blog" },
32
- { text: "Careers", href: "/careers" },
33
- { text: "Contact", href: "/contact" }
34
- ]
35
- },
36
- {
37
- title: "Resources",
38
- links: [
39
- { text: "Community", href: "/community" },
40
- { text: "Help Center", href: "/help" },
41
- { text: "Status", href: "/status" },
42
- { text: "Terms", href: "/terms" }
43
- ]
44
- }
45
- ];
46
-
6
+ // Use $derived for reactive configuration
7
+ let config = $derived(footerStore.config);
8
+
47
9
  // Current year for copyright
48
10
  const currentYear = new Date().getFullYear();
49
11
  </script>
50
12
 
51
- <footer class="footer p-10 bg-base-200 text-base-content">
52
- <!-- Logo and company info -->
53
- <aside class="flex flex-col items-start gap-4">
54
- <img
55
- src="/favicon.png"
56
- alt="{appData.name} Logo"
57
- class="h-12 w-12 rounded-lg hover:animate-pulse"
58
- />
59
- <div>
60
- <h2 class="text-lg font-bold">{appData.name}</h2>
61
- <p class="text-sm opacity-75">
62
- Building better software<br/>
63
- since {currentYear}
64
- </p>
65
- </div>
13
+ {#if config.sections.length > 0}
14
+ <footer class="footer p-10 bg-base-200 text-base-content">
15
+ <!-- Logo and company info -->
16
+ <aside class="flex flex-col items-start gap-4">
17
+ <img
18
+ src="/favicon.png"
19
+ alt="{appData.name} Logo"
20
+ class="h-12 w-12 rounded-lg hover:animate-pulse"
21
+ />
22
+ <div>
23
+ <h2 class="text-lg font-bold">{appData.name}</h2>
24
+ <p class="text-sm opacity-75">
25
+ Building better software<br/>
26
+ since {currentYear}
27
+ </p>
28
+ </div>
66
29
 
67
- <!-- Social media links -->
68
- <div class="flex gap-4">
69
- <a
70
- href="https://github.com/Yrrrrrf"
71
- aria-label="Visit my GitHub profile"
72
- class="btn btn-circle btn-ghost btn-sm hover:text-primary"
73
- >
74
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
75
- <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
76
- </svg>
77
- </a>
78
- <a
79
- href="https://twitter.com"
80
- aria-label="Visit my Twitter profile"
81
- class="btn btn-circle btn-ghost btn-sm hover:text-primary"
82
- >
83
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
84
- <path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
85
- </svg>
86
- </a>
87
- <a
88
- href="https://linkedin.com"
89
- aria-label="Visit my LinkedIn profile"
90
- class="btn btn-circle btn-ghost btn-sm hover:text-primary"
91
- >
92
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
93
- <path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
94
- </svg>
95
- </a>
96
- </div>
30
+ <!-- Social media links -->
31
+ {#if config.showSocialLinks}
32
+ <div class="flex gap-4">
33
+ {#if config.socialLinks.github}
34
+ <a href={config.socialLinks.github}
35
+ class="btn btn-circle btn-ghost btn-sm hover:text-primary"
36
+ aria-label="Visit GitHub profile">
37
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
38
+ <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
39
+ </svg>
40
+ </a>
41
+ {/if}
42
+
43
+ {#if config.socialLinks.twitter}
44
+ <a href={config.socialLinks.twitter}
45
+ class="btn btn-circle btn-ghost btn-sm hover:text-primary"
46
+ aria-label="Visit Twitter profile">
47
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
48
+ <path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
49
+ </svg>
50
+ </a>
51
+ {/if}
52
+
53
+ {#if config.socialLinks.linkedin}
54
+ <a href={config.socialLinks.linkedin}
55
+ class="btn btn-circle btn-ghost btn-sm hover:text-primary"
56
+ aria-label="Visit LinkedIn profile">
57
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
58
+ <path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
59
+ </svg>
60
+ </a>
61
+ {/if}
62
+ </div>
63
+ {/if}
64
+ </aside>
97
65
 
98
- <!-- Navigation sections -->
99
- {#each footerSections as section}
100
- <nav>
101
- <h6 class="footer-title">{section.title}</h6>
102
- {#each section.links as link}
103
- <a href={link.href} class="link link-hover">{link.text}</a>
104
- {/each}
105
- </nav>
106
- {/each}
107
- </footer>
66
+ <!-- Navigation sections -->
67
+ {#each config.sections as section}
68
+ <nav>
69
+ <h6 class="footer-title">{section.title}</h6>
70
+ {#each section.links as link}
71
+ <a href={link.href} class="link link-hover">{link.text}</a>
72
+ {/each}
73
+ </nav>
74
+ {/each}
75
+ </footer>
108
76
 
109
- <!-- Copyright footer -->
110
- <footer class="footer footer-center p-4 bg-base-300 text-base-content">
111
- <aside class="flex flex-col items-center gap-2">
112
- <p>Copyright © {currentYear} {appData.name} - All rights reserved</p>
113
- <p class="text-sm opacity-75">Version {appData.version}</p>
114
- </aside>
115
- </footer>
77
+ <!-- Copyright footer -->
78
+ {#if config.showCopyright}
79
+ <footer class="footer footer-center p-4 bg-base-300 text-base-content">
80
+ <aside class="flex flex-col items-center gap-2">
81
+ <p>Copyright © {currentYear} {appData.name} - All rights reserved</p>
82
+ {#if config.showVersion}
83
+ <p class="text-sm opacity-75">Version {appData.version}</p>
84
+ {/if}
85
+ </aside>
86
+ </footer>
87
+ {/if}
88
+ {/if}
@@ -1,18 +1,3 @@
1
- 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> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
13
- }
14
- declare const Footer: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type Footer = InstanceType<typeof Footer>;
1
+ declare const Footer: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type Footer = ReturnType<typeof Footer>;
18
3
  export default Footer;
@@ -0,0 +1,134 @@
1
+ <script lang="ts">
2
+ import {
3
+ MagnifyingGlass,
4
+ Gear,
5
+ User,
6
+ // Pills,
7
+ // Activity,
8
+ SignIn,
9
+ SignOut,
10
+ Bell,
11
+ ShoppingCart
12
+ } from 'phosphor-svelte';
13
+
14
+ // Import stores
15
+ import { appData } from '../../stores/app.svelte.js';
16
+ import { authStore } from '../../stores/auth.svelte.js';
17
+ import { themeStore } from '../../stores/theme.svelte.js';
18
+
19
+ // Optional components you can import
20
+ import ThemeSelector from './ThemeSelector.svelte';
21
+
22
+ // State using Runes
23
+ let isSearchActive = $state(false);
24
+ let searchQuery = $state('');
25
+ let notificationCount = $state(3);
26
+
27
+ // Navigation items with proper typing
28
+ type NavItem = {
29
+ icon: any; // PhosphorIcon type
30
+ label: string;
31
+ path: string;
32
+ requiresAuth: boolean;
33
+ };
34
+
35
+ function handleSearch(e: KeyboardEvent) {
36
+ if (e.key === 'Enter' && searchQuery.trim()) {
37
+ // Handle search - you might want to emit an event
38
+ isSearchActive = false;
39
+ } else if (e.key === 'Escape') {
40
+ isSearchActive = false;
41
+ }
42
+ }
43
+
44
+ function handleLogin() {
45
+ // Example login
46
+ authStore.login({
47
+ id: '1',
48
+ name: 'Test User',
49
+ email: 'test@example.com',
50
+ role: 'staff'
51
+ });
52
+ }
53
+ </script>
54
+
55
+ <nav class="navbar bg-base-100">
56
+ <!-- Logo Section -->
57
+ <div class="flex-1">
58
+ <a href="/" class="btn btn-ghost normal-case text-xl gap-2">
59
+ <div class="w-10 h-10">
60
+ <img
61
+ src="/favicon.png"
62
+ alt="{appData.name} Logo"
63
+ class="w-full h-full object-contain rounded-full hover:animate-spin"
64
+ />
65
+ </div>
66
+ <span>{appData.name}</span>
67
+ </a>
68
+ </div>
69
+
70
+ <div class="flex-none gap-2">
71
+
72
+ <!-- Search -->
73
+ {#if isSearchActive}
74
+ <div class="form-control">
75
+ <input
76
+ type="text"
77
+ placeholder="Search..."
78
+ bind:value={searchQuery}
79
+ onkeydown={handleSearch}
80
+ class="input input-bordered"
81
+ />
82
+ </div>
83
+ {:else}
84
+ <button
85
+ class="btn btn-ghost btn-circle"
86
+ onclick={() => isSearchActive = true}
87
+ aria-label="Search"
88
+ >
89
+ <MagnifyingGlass size={20} weight="bold" />
90
+ </button>
91
+ {/if}
92
+
93
+ <!-- Authenticated Content -->
94
+ {#if authStore.isAuthenticated}
95
+ <!-- Notifications -->
96
+ <div class="dropdown dropdown-end">
97
+ <button class="btn btn-ghost btn-circle" aria-label="Notifications">
98
+ <div class="indicator">
99
+ <Bell size={20} weight="bold" />
100
+ {#if notificationCount > 0}
101
+ <span class="badge badge-sm indicator-item">{notificationCount}</span>
102
+ {/if}
103
+ </div>
104
+ </button>
105
+ </div>
106
+
107
+ <!-- User Menu -->
108
+ <div class="dropdown dropdown-end">
109
+ <button class="btn btn-ghost btn-circle avatar" aria-label="User menu">
110
+ <div class="w-10 rounded-full">
111
+ <img src="https://api.dicebear.com/7.x/avataaars/svg?seed={authStore.user?.name}" alt="User avatar" />
112
+ </div>
113
+ </button>
114
+ <ul class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
115
+ <li><a href="/profile"><User size={16} weight="bold" /> Profile</a></li>
116
+ <li><a href="/settings"><Gear size={16} weight="bold" /> Settings</a></li>
117
+ <li><button onclick={() => authStore.logout()}><SignOut size={16} weight="bold" /> Logout</button></li>
118
+ </ul>
119
+ </div>
120
+ {:else}
121
+ <!-- Login Button -->
122
+ <button class="btn btn-primary btn-sm" onclick={handleLogin}>
123
+ <SignIn size={16} weight="bold" />
124
+ Sign In
125
+ </button>
126
+ {/if}
127
+
128
+ <!-- Theme Selector -->
129
+ <!-- if isAuthenticated show the theme selector -->
130
+ {#if authStore.isAuthenticated}
131
+ <ThemeSelector />
132
+ {/if}
133
+ </div>
134
+ </nav>
@@ -0,0 +1,3 @@
1
+ declare const NavBar: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type NavBar = ReturnType<typeof NavBar>;
3
+ export default NavBar;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ // jdaslkfjsklsajdklj
2
3
  import { themeStore } from '../../stores/theme.svelte.js';
3
4
 
4
5
  // Local state using runes
@@ -16,7 +17,7 @@
16
17
  }
17
18
  </script>
18
19
 
19
- <div class="theme-selector">
20
+ <div class="relative">
20
21
  <button
21
22
  class="btn"
22
23
  onclick={() => showDropdown = !showDropdown}
@@ -25,12 +26,12 @@
25
26
  </button>
26
27
 
27
28
  {#if showDropdown}
28
- <ul class="theme-menu">
29
+ <ul class="absolute right-0 top-full mt-2 min-w-[150px] p-2 bg-base-100 border border-base-300 rounded-lg shadow-lg">
29
30
  {#each themes as theme}
30
31
  <li>
31
32
  <button
32
- class="theme-option"
33
- class:active={themeStore.currentTheme === theme.value}
33
+ class="w-full flex items-center gap-2 px-2 py-2 text-left hover:bg-base-200 transition-colors duration-200 rounded-lg
34
+ {themeStore.currentTheme === theme.value ? 'bg-base-300' : ''}"
34
35
  onclick={() => handleThemeSelect(theme.value)}
35
36
  >
36
37
  <span>{theme.icon}</span>
@@ -40,39 +41,4 @@
40
41
  {/each}
41
42
  </ul>
42
43
  {/if}
43
- </div>
44
-
45
- <style>
46
- .theme-selector {
47
- position: relative;
48
- }
49
-
50
- .theme-menu {
51
- position: absolute;
52
- right: 0;
53
- top: 100%;
54
- margin-top: 0.5rem;
55
- background: var(--background);
56
- border: 1px solid var(--border);
57
- border-radius: 0.5rem;
58
- padding: 0.5rem;
59
- min-width: 150px;
60
- }
61
-
62
- .theme-option {
63
- display: flex;
64
- align-items: center;
65
- gap: 0.5rem;
66
- padding: 0.5rem;
67
- width: 100%;
68
- text-align: left;
69
- }
70
-
71
- .theme-option:hover {
72
- background: var(--hover);
73
- }
74
-
75
- .active {
76
- background: var(--active);
77
- }
78
- </style>
44
+ </div>
package/dist/index.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export { default as UIShowcase } from './components/UIShowcase.svelte';
2
- export { appData, type AppData } from './stores/app.svelte.js';
3
- export { apiStore, type ApiStore } from './stores/api.svelte.js';
2
+ export { default as Altharun } from './components/dt/Altharun.svelte';
3
+ export { default as Kyntharil } from './components/dt/Kyntharil.svelte';
4
+ export { default as NavBar } from './components/layout/NavBar.svelte';
4
5
  export { default as UrlDisplay } from './components/layout/URLDisplay.svelte';
5
6
  export { default as Footer } from './components/layout/Footer.svelte';
6
7
  export { themeStore } from './stores/theme.svelte.js';
7
8
  export { default as ThemeSelector } from './components/layout/ThemeSelector.svelte';
9
+ export { footerStore, type FooterLink, type FooterConfig, type FooterSection } from './stores/layout/footer.svelte.js';
10
+ export { appData, type AppData } from './stores/app.svelte.js';
11
+ export { apiStore, type ApiStore } from './stores/api.svelte.js';
12
+ export { authStore, type AuthState } from './stores/auth.svelte.js';
13
+ export { databaseStore, type DatabaseState, } from './stores/db.svelte.js';
package/dist/index.js CHANGED
@@ -2,10 +2,15 @@
2
2
  // * UI Library entry point...
3
3
  // ^ UI Showcase
4
4
  export { default as UIShowcase } from './components/UIShowcase.svelte';
5
- // ^ App related components
6
- export { appData } from './stores/app.svelte.js';
7
- export { apiStore } from './stores/api.svelte.js';
5
+ // * RUENES OF...
6
+ // * Kyntharil
7
+ // * from Old Norse "kyn" = kind, kin + suffix -tharil suggesting evolution
8
+ export { default as Altharun } from './components/dt/Altharun.svelte';
9
+ // * Altharun
10
+ // * from Old Norse "aldir" = age, wisdom
11
+ export { default as Kyntharil } from './components/dt/Kyntharil.svelte';
8
12
  // layout related components
13
+ export { default as NavBar } from './components/layout/NavBar.svelte';
9
14
  export { default as UrlDisplay } from './components/layout/URLDisplay.svelte';
10
15
  export { default as Footer } from './components/layout/Footer.svelte';
11
16
  // ^ data related components
@@ -23,3 +28,14 @@ export { default as ThemeSelector } from './components/layout/ThemeSelector.svel
23
28
  // export * from './components/tools/qr.js';
24
29
  // export * from './components/tools/uuid.js';
25
30
  // export * from './components/tools/validate.js';
31
+ // * I don't know if this is some allusion or something...
32
+ // * But I think that if I import this later, (I mean, at last)
33
+ // * This fix some of the problems with the store management...
34
+ // * I don't know why, but it works...
35
+ // todo: investigate why this works...
36
+ // ^ App related components
37
+ export { footerStore } from './stores/layout/footer.svelte.js';
38
+ export { appData } from './stores/app.svelte.js';
39
+ export { apiStore } from './stores/api.svelte.js';
40
+ export { authStore } from './stores/auth.svelte.js';
41
+ export { databaseStore, } from './stores/db.svelte.js';
@@ -12,7 +12,7 @@ class AppStore {
12
12
  this.description = data.description;
13
13
  if (data.author)
14
14
  this.author = data.author;
15
- // console.clear();
15
+ console.clear();
16
16
  console.log('🔮 App initialized:', {
17
17
  name: this.name,
18
18
  version: this.version,
@@ -0,0 +1,19 @@
1
+ export interface User {
2
+ id: string;
3
+ name: string;
4
+ email: string;
5
+ role: 'admin' | 'staff' | 'user';
6
+ }
7
+ export interface AuthState {
8
+ isAuthenticated: boolean;
9
+ user: User | null;
10
+ }
11
+ declare class AuthStore {
12
+ isAuthenticated: boolean;
13
+ user: User | null;
14
+ login(user: User): void;
15
+ logout(): void;
16
+ init(initialState?: Partial<AuthState>): void;
17
+ }
18
+ export declare const authStore: AuthStore;
19
+ export {};
@@ -0,0 +1,26 @@
1
+ // src/lib/stores/auth.svelte.ts
2
+ class AuthStore {
3
+ isAuthenticated = $state(false);
4
+ user = $state(null);
5
+ login(user) {
6
+ this.isAuthenticated = true;
7
+ this.user = user;
8
+ console.log('🔐 User logged in:', user);
9
+ }
10
+ logout() {
11
+ this.isAuthenticated = false;
12
+ this.user = null;
13
+ console.log('👋 User logged out');
14
+ }
15
+ init(initialState) {
16
+ if (initialState?.isAuthenticated)
17
+ this.isAuthenticated = initialState.isAuthenticated;
18
+ if (initialState?.user)
19
+ this.user = initialState.user;
20
+ console.log('🔑 Auth initialized:', {
21
+ isAuthenticated: this.isAuthenticated,
22
+ user: this.user
23
+ });
24
+ }
25
+ }
26
+ export const authStore = new AuthStore();
@@ -0,0 +1,27 @@
1
+ import { type SchemaMetadata } from "ts-forge";
2
+ export interface DatabaseState {
3
+ schemas: Record<string, SchemaMetadata>;
4
+ tables: Record<string, Record<string, any>>;
5
+ activeSchema: string | null;
6
+ activeTable: string | null;
7
+ showModal: boolean;
8
+ currentOperation: 'POST' | 'GET' | 'PUT' | 'DELETE' | null;
9
+ }
10
+ declare class DatabaseStore {
11
+ schemas: Record<string, SchemaMetadata>;
12
+ tables: Record<string, Record<string, any>>;
13
+ activeSchema: string | null;
14
+ activeTable: string | null;
15
+ showModal: boolean;
16
+ currentOperation: "GET" | "POST" | "PUT" | "DELETE" | null;
17
+ currentTables: SchemaMetadata | null;
18
+ toggleSchema(schema: string): void;
19
+ private baseClient;
20
+ private forge;
21
+ setActiveTable(schema: string, table: string): void;
22
+ setOperation(operation: DatabaseState['currentOperation']): void;
23
+ handleCrudOperation(operation: DatabaseState['currentOperation']): Promise<void>;
24
+ init(): Promise<void>;
25
+ }
26
+ export declare const databaseStore: DatabaseStore;
27
+ export {};
@@ -0,0 +1,51 @@
1
+ // src/lib/stores/database.svelte.ts
2
+ import { BaseClient, TsForge } from "ts-forge";
3
+ class DatabaseStore {
4
+ // Core state with proper initialization
5
+ schemas = $state({});
6
+ tables = $state({});
7
+ activeSchema = $state(null);
8
+ activeTable = $state(null);
9
+ showModal = $state(false);
10
+ currentOperation = $state(null);
11
+ // Change this derived state
12
+ currentTables = $derived(this.activeSchema ? this.schemas[this.activeSchema] : null);
13
+ toggleSchema(schema) {
14
+ // Simple toggle, don't clear if already active
15
+ this.activeSchema = schema;
16
+ console.log('Active schema:', this.activeSchema, 'Tables:', this.schemas[schema]);
17
+ }
18
+ // Base client
19
+ baseClient = new BaseClient('http://localhost:8000/');
20
+ forge = new TsForge(this.baseClient);
21
+ // Table management
22
+ setActiveTable(schema, table) {
23
+ this.activeSchema = schema;
24
+ this.activeTable = table;
25
+ console.log('Set active:', { schema, table });
26
+ }
27
+ // CRUD operations
28
+ setOperation(operation) {
29
+ this.currentOperation = operation;
30
+ this.showModal = !!operation;
31
+ }
32
+ async handleCrudOperation(operation) {
33
+ this.setOperation(operation);
34
+ }
35
+ // Initialize the store
36
+ async init() {
37
+ try {
38
+ await this.forge.init();
39
+ this.schemas = this.forge.schemaLookup;
40
+ console.log('Database store initialized:', {
41
+ schemas: Object.keys(this.schemas)
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error('Database store initialization failed:', error);
46
+ throw error;
47
+ }
48
+ }
49
+ }
50
+ // Export singleton instance
51
+ export const databaseStore = new DatabaseStore();
@@ -0,0 +1,35 @@
1
+ export interface FooterLink {
2
+ text: string;
3
+ href: string;
4
+ }
5
+ export interface FooterSection {
6
+ title: string;
7
+ links: FooterLink[];
8
+ }
9
+ export interface FooterConfig {
10
+ sections: FooterSection[];
11
+ socialLinks: {
12
+ github?: string;
13
+ twitter?: string;
14
+ linkedin?: string;
15
+ };
16
+ showSocialLinks: boolean;
17
+ showVersion: boolean;
18
+ showCopyright: boolean;
19
+ }
20
+ declare class FooterStore {
21
+ private _config;
22
+ get config(): FooterConfig;
23
+ init(config: Partial<FooterConfig>): this;
24
+ reset(): this;
25
+ addSection(section: FooterSection): this;
26
+ updateSection(index: number, section: FooterSection): this;
27
+ removeSection(index: number): this;
28
+ clearSections(): this;
29
+ updateSocialLinks(links: Partial<FooterConfig['socialLinks']>): this;
30
+ showSocialLinks(show: boolean): this;
31
+ showVersion(show: boolean): this;
32
+ showCopyright(show: boolean): this;
33
+ }
34
+ export declare const footerStore: FooterStore;
35
+ export {};