create-nara 1.0.3 → 1.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nara",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "CLI to scaffold NARA projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { fly, fade } from 'svelte/transition';
3
3
  import { page, router, inertia } from '@inertiajs/svelte';
4
- import { clickOutside } from '../Components/helper';
5
- import DarkModeToggle from '../Components/DarkModeToggle.svelte';
4
+ import { clickOutside } from '../components/helper';
5
+ import DarkModeToggle from '../components/DarkModeToggle.svelte';
6
6
 
7
7
  interface User {
8
8
  id: string;
@@ -1,76 +1,233 @@
1
1
  @import url('https://rsms.me/inter/inter.css');
2
2
  @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400&display=swap');
3
- @tailwind base;
4
- @tailwind components;
5
- @tailwind utilities;
3
+ @import "tailwindcss";
6
4
 
7
- @layer base {
8
- html {
9
- font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
10
- }
5
+ /* Custom theme colors using CSS variables */
6
+ @theme {
7
+ --color-primary-50: #ecfdf5;
8
+ --color-primary-100: #d1fae5;
9
+ --color-primary-200: #a7f3d0;
10
+ --color-primary-300: #6ee7b7;
11
+ --color-primary-400: #34d399;
12
+ --color-primary-500: #10b981;
13
+ --color-primary-600: #059669;
14
+ --color-primary-700: #047857;
15
+ --color-primary-800: #065f46;
16
+ --color-primary-900: #064e3b;
17
+ --color-primary-950: #022c22;
11
18
 
12
- body::-webkit-scrollbar {
13
- width: 4px;
14
- }
19
+ --color-secondary-50: #fffbeb;
20
+ --color-secondary-100: #fef3c7;
21
+ --color-secondary-200: #fde68a;
22
+ --color-secondary-300: #fcd34d;
23
+ --color-secondary-400: #fbbf24;
24
+ --color-secondary-500: #f59e0b;
25
+ --color-secondary-600: #d97706;
26
+ --color-secondary-700: #b45309;
27
+ --color-secondary-800: #92400e;
28
+ --color-secondary-900: #78350f;
29
+ --color-secondary-950: #451a03;
15
30
 
16
- body::-webkit-scrollbar-track {
17
- background: transparent;
18
- }
31
+ --color-accent-50: #faf5ff;
32
+ --color-accent-100: #f3e8ff;
33
+ --color-accent-200: #e9d5ff;
34
+ --color-accent-300: #d8b4fe;
35
+ --color-accent-400: #c084fc;
36
+ --color-accent-500: #a855f7;
37
+ --color-accent-600: #9333ea;
38
+ --color-accent-700: #7c3aed;
39
+ --color-accent-800: #6b21a8;
40
+ --color-accent-900: #581c87;
41
+ --color-accent-950: #3b0764;
19
42
 
20
- body::-webkit-scrollbar-thumb {
21
- background-color: theme('colors.primary.500');
22
- border-radius: 3px;
23
- }
43
+ --color-info-50: #ecfeff;
44
+ --color-info-100: #cffafe;
45
+ --color-info-200: #a5f3fc;
46
+ --color-info-300: #67e8f9;
47
+ --color-info-400: #22d3ee;
48
+ --color-info-500: #06b6d4;
49
+ --color-info-600: #0891b2;
50
+ --color-info-700: #0e7490;
51
+ --color-info-800: #155e75;
52
+ --color-info-900: #164e63;
53
+ --color-info-950: #083344;
54
+
55
+ --color-warning-50: #fff7ed;
56
+ --color-warning-100: #ffedd5;
57
+ --color-warning-200: #fed7aa;
58
+ --color-warning-300: #fdba74;
59
+ --color-warning-400: #fb923c;
60
+ --color-warning-500: #f97316;
61
+ --color-warning-600: #ea580c;
62
+ --color-warning-700: #c2410c;
63
+ --color-warning-800: #9a3412;
64
+ --color-warning-900: #7c2d12;
65
+ --color-warning-950: #431407;
66
+
67
+ --color-danger-50: #fef2f2;
68
+ --color-danger-100: #fee2e2;
69
+ --color-danger-200: #fecaca;
70
+ --color-danger-300: #fca5a5;
71
+ --color-danger-400: #f87171;
72
+ --color-danger-500: #ef4444;
73
+ --color-danger-600: #dc2626;
74
+ --color-danger-700: #b91c1c;
75
+ --color-danger-800: #991b1b;
76
+ --color-danger-900: #7f1d1d;
77
+ --color-danger-950: #450a0a;
78
+
79
+ --color-success-50: #ecfdf5;
80
+ --color-success-100: #d1fae5;
81
+ --color-success-200: #a7f3d0;
82
+ --color-success-300: #6ee7b7;
83
+ --color-success-400: #34d399;
84
+ --color-success-500: #10b981;
85
+ --color-success-600: #059669;
86
+ --color-success-700: #047857;
87
+ --color-success-800: #065f46;
88
+ --color-success-900: #064e3b;
89
+ --color-success-950: #022c22;
90
+
91
+ --color-surface-light: #f8f8f8;
92
+ --color-surface-dark: #0a0a0a;
93
+ --color-surface-card-light: #f1f5f9;
94
+ --color-surface-card-dark: #0f0f0f;
95
+
96
+ --font-family-sans: 'Inter var', 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
97
+ --font-family-serif: 'Playfair Display', Georgia, Cambria, 'Times New Roman', Times, serif;
98
+
99
+ --shadow-soft: 0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04);
24
100
  }
25
101
 
26
- @layer components {
27
- .card-hover {
28
- @apply transition-all duration-300 hover:shadow-soft hover:-translate-y-1;
29
- }
102
+ /* Base styles */
103
+ html {
104
+ font-family: var(--font-family-sans);
105
+ }
30
106
 
31
- .nav-link {
32
- @apply px-4 py-2 text-gray-600 dark:text-gray-200 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors duration-300;
33
- }
107
+ body::-webkit-scrollbar {
108
+ width: 4px;
109
+ }
34
110
 
35
- .nav-link.active {
36
- @apply bg-primary-50 dark:bg-gray-800 text-primary-600;
37
- }
111
+ body::-webkit-scrollbar-track {
112
+ background: transparent;
113
+ }
38
114
 
39
- .gradient-text {
40
- @apply bg-clip-text text-transparent bg-gradient-to-r from-primary-600 to-primary-400;
41
- }
115
+ body::-webkit-scrollbar-thumb {
116
+ background-color: var(--color-primary-500);
117
+ border-radius: 3px;
118
+ }
42
119
 
43
- .btn-primary {
44
- @apply bg-primary-600 text-white px-4 py-2 rounded-lg hover:bg-primary-700
45
- transition-all duration-300 active:bg-primary-800
46
- disabled:opacity-50 disabled:cursor-not-allowed
47
- focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
120
+ /* Component utilities */
121
+ @utility card-hover {
122
+ transition-property: all;
123
+ transition-duration: 300ms;
124
+ &:hover {
125
+ box-shadow: var(--shadow-soft);
126
+ transform: translateY(-0.25rem);
48
127
  }
128
+ }
49
129
 
50
- .btn-secondary {
51
- @apply bg-white text-gray-900 px-4 py-2 rounded-lg border border-gray-300
52
- hover:bg-gray-50 transition-all duration-300 active:bg-gray-100
53
- disabled:opacity-50 disabled:cursor-not-allowed
54
- focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2;
130
+ @utility nav-link {
131
+ padding: 0.5rem 1rem;
132
+ color: rgb(75 85 99);
133
+ border-radius: 0.5rem;
134
+ transition-property: color, background-color;
135
+ transition-duration: 300ms;
136
+ &:hover {
137
+ color: rgb(17 24 39);
138
+ background-color: rgb(243 244 246);
55
139
  }
140
+ }
56
141
 
57
- .btn-danger {
58
- @apply bg-danger-600 text-white px-4 py-2 rounded-lg hover:bg-danger-700
59
- transition-all duration-300 active:bg-danger-800
60
- disabled:opacity-50 disabled:cursor-not-allowed
61
- focus:outline-none focus:ring-2 focus:ring-danger-500 focus:ring-offset-2;
142
+ @utility gradient-text {
143
+ background-clip: text;
144
+ -webkit-background-clip: text;
145
+ color: transparent;
146
+ background-image: linear-gradient(to right, var(--color-primary-600), var(--color-primary-400));
147
+ }
148
+
149
+ @utility btn-primary {
150
+ background-color: var(--color-primary-600);
151
+ color: white;
152
+ padding: 0.5rem 1rem;
153
+ border-radius: 0.5rem;
154
+ transition-property: all;
155
+ transition-duration: 300ms;
156
+ &:hover {
157
+ background-color: var(--color-primary-700);
158
+ }
159
+ &:active {
160
+ background-color: var(--color-primary-800);
62
161
  }
162
+ &:disabled {
163
+ opacity: 0.5;
164
+ cursor: not-allowed;
165
+ }
166
+ &:focus {
167
+ outline: none;
168
+ box-shadow: 0 0 0 2px white, 0 0 0 4px var(--color-primary-500);
169
+ }
170
+ }
63
171
 
64
- .card {
65
- @apply bg-white rounded-xl shadow-soft p-6 transition-all duration-300
66
- shadow-lg hover:shadow-xl hover:-translate-y-0.5;
172
+ @utility btn-secondary {
173
+ background-color: white;
174
+ color: rgb(17 24 39);
175
+ padding: 0.5rem 1rem;
176
+ border-radius: 0.5rem;
177
+ border: 1px solid rgb(209 213 219);
178
+ transition-property: all;
179
+ transition-duration: 300ms;
180
+ &:hover {
181
+ background-color: rgb(249 250 251);
182
+ }
183
+ &:active {
184
+ background-color: rgb(243 244 246);
67
185
  }
186
+ &:disabled {
187
+ opacity: 0.5;
188
+ cursor: not-allowed;
189
+ }
190
+ &:focus {
191
+ outline: none;
192
+ box-shadow: 0 0 0 2px white, 0 0 0 4px rgb(107 114 128);
193
+ }
194
+ }
68
195
 
69
- .bg-surface {
70
- @apply bg-surface-light dark:bg-surface-dark;
196
+ @utility btn-danger {
197
+ background-color: var(--color-danger-600);
198
+ color: white;
199
+ padding: 0.5rem 1rem;
200
+ border-radius: 0.5rem;
201
+ transition-property: all;
202
+ transition-duration: 300ms;
203
+ &:hover {
204
+ background-color: var(--color-danger-700);
205
+ }
206
+ &:active {
207
+ background-color: var(--color-danger-800);
71
208
  }
209
+ &:disabled {
210
+ opacity: 0.5;
211
+ cursor: not-allowed;
212
+ }
213
+ &:focus {
214
+ outline: none;
215
+ box-shadow: 0 0 0 2px white, 0 0 0 4px var(--color-danger-500);
216
+ }
217
+ }
72
218
 
73
- .bg-surface-card {
74
- @apply bg-surface-card-light dark:bg-surface-card-dark;
219
+ @utility card {
220
+ background-color: white;
221
+ border-radius: 0.75rem;
222
+ box-shadow: var(--shadow-soft);
223
+ padding: 1.5rem;
224
+ transition-property: all;
225
+ transition-duration: 300ms;
226
+ &:hover {
227
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
228
+ transform: translateY(-0.125rem);
75
229
  }
76
230
  }
231
+
232
+ /* Surface utilities - use standard Tailwind classes instead */
233
+ /* bg-surface-light, bg-surface-dark, bg-surface-card-light, bg-surface-card-dark are available */
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { inertia, router } from "@inertiajs/svelte";
3
- import NaraIcon from "../../Components/NaraIcon.svelte";
4
- import DarkModeToggle from "../../Components/DarkModeToggle.svelte";
3
+ import NaraIcon from "../../components/NaraIcon.svelte";
4
+ import DarkModeToggle from "../../components/DarkModeToggle.svelte";
5
5
  import axios from "axios";
6
- import { api, Toast } from "../../Components/helper";
6
+ import { api, Toast } from "../../components/helper";
7
7
 
8
8
  interface ForgotPasswordForm {
9
9
  email: string;
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
3
  import { inertia, router } from '@inertiajs/svelte'
4
- import { Toast } from '../../Components/helper';
5
- import NaraIcon from '../../Components/NaraIcon.svelte';
4
+ import { Toast } from '../../components/helper';
5
+ import NaraIcon from '../../components/NaraIcon.svelte';
6
6
  import { fade, fly } from 'svelte/transition';
7
7
 
8
8
  onMount(() => {
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
3
  import { inertia, router } from '@inertiajs/svelte'
4
- import { password_generator, Toast } from '../../Components/helper';
5
- import NaraIcon from '../../Components/NaraIcon.svelte';
4
+ import { password_generator, Toast } from '../../components/helper';
5
+ import NaraIcon from '../../components/NaraIcon.svelte';
6
6
  import { fade, fly } from 'svelte/transition';
7
7
 
8
8
  onMount(() => {
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { inertia, router } from '@inertiajs/svelte'
3
- import NaraIcon from '../../Components/NaraIcon.svelte';
4
- import DarkModeToggle from '../../Components/DarkModeToggle.svelte';
5
- import { password_generator, Toast } from '../../Components/helper';
3
+ import NaraIcon from '../../components/NaraIcon.svelte';
4
+ import DarkModeToggle from '../../components/DarkModeToggle.svelte';
5
+ import { password_generator, Toast } from '../../components/helper';
6
6
 
7
7
  interface ResetPasswordForm {
8
8
  password: string;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { fly } from 'svelte/transition';
3
3
  import { page as inertiaPage, inertia } from '@inertiajs/svelte';
4
- import Header from '../Components/Header.svelte';
4
+ import Header from '../components/Header.svelte';
5
5
  import type { User } from '../types';
6
6
 
7
7
  export let users: User[] = [];
@@ -2,7 +2,7 @@
2
2
  import { inertia, page } from '@inertiajs/svelte'
3
3
  import { fade, fly } from 'svelte/transition'
4
4
  import { onMount } from 'svelte'
5
- import DarkModeToggle from '../Components/DarkModeToggle.svelte'
5
+ import DarkModeToggle from '../components/DarkModeToggle.svelte'
6
6
 
7
7
  interface User {
8
8
  id: string;
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { fly } from 'svelte/transition';
3
3
  import axios from "axios";
4
- import Header from "../Components/Header.svelte";
5
- import { api, Toast } from "../Components/helper";
4
+ import Header from "../components/Header.svelte";
5
+ import { api, Toast } from "../components/helper";
6
6
 
7
7
  interface User {
8
8
  id: string;
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { fly } from 'svelte/transition';
3
3
  import { page as inertiaPage, router } from '@inertiajs/svelte';
4
- import Header from '../Components/Header.svelte';
5
- import UserModal from '../Components/UserModal.svelte';
6
- import Pagination from '../Components/Pagination.svelte';
4
+ import Header from '../components/Header.svelte';
5
+ import UserModal from '../components/UserModal.svelte';
6
+ import Pagination from '../components/Pagination.svelte';
7
7
  import axios from 'axios';
8
- import { api, Toast } from '../Components/helper';
8
+ import { api, Toast } from '../components/helper';
9
9
  import type { User, UserForm, PaginationMeta } from '../types';
10
10
  import { createEmptyUserForm, userToForm } from '../types';
11
11
 
@@ -0,0 +1,50 @@
1
+ // User types
2
+ export interface User {
3
+ id: string;
4
+ name: string;
5
+ email: string;
6
+ is_admin: boolean;
7
+ is_verified: boolean;
8
+ created_at?: string;
9
+ updated_at?: string;
10
+ }
11
+
12
+ // User form for create/edit
13
+ export interface UserForm {
14
+ id?: string;
15
+ name: string;
16
+ email: string;
17
+ password: string;
18
+ is_admin: boolean;
19
+ }
20
+
21
+ // Pagination meta from backend
22
+ export interface PaginationMeta {
23
+ total: number;
24
+ page: number;
25
+ limit: number;
26
+ totalPages: number;
27
+ hasNext: boolean;
28
+ hasPrev: boolean;
29
+ }
30
+
31
+ // Helper to create empty user form
32
+ export function createEmptyUserForm(): UserForm {
33
+ return {
34
+ name: '',
35
+ email: '',
36
+ password: '',
37
+ is_admin: false,
38
+ };
39
+ }
40
+
41
+ // Helper to convert User to UserForm for editing
42
+ export function userToForm(user: User): UserForm {
43
+ return {
44
+ id: user.id,
45
+ name: user.name,
46
+ email: user.email,
47
+ password: '',
48
+ is_admin: user.is_admin,
49
+ };
50
+ }
@@ -1,120 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- export default {
3
- content: [
4
- "./resources/**/*.{svelte,html,js,ts}",
5
- ],
6
- darkMode: 'class',
7
- theme: {
8
- extend: {
9
- fontFamily: {
10
- sans: ['Inter var', 'Inter', 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'],
11
- serif: ['Playfair Display', 'Georgia', 'Cambria', 'Times New Roman', 'Times', 'serif'],
12
- },
13
- colors: {
14
- primary: {
15
- 50: '#ecfdf5',
16
- 100: '#d1fae5',
17
- 200: '#a7f3d0',
18
- 300: '#6ee7b7',
19
- 400: '#34d399',
20
- 500: '#10b981',
21
- 600: '#059669',
22
- 700: '#047857',
23
- 800: '#065f46',
24
- 900: '#064e3b',
25
- 950: '#022c22',
26
- },
27
- secondary: {
28
- 50: '#fffbeb',
29
- 100: '#fef3c7',
30
- 200: '#fde68a',
31
- 300: '#fcd34d',
32
- 400: '#fbbf24',
33
- 500: '#f59e0b',
34
- 600: '#d97706',
35
- 700: '#b45309',
36
- 800: '#92400e',
37
- 900: '#78350f',
38
- 950: '#451a03',
39
- },
40
- accent: {
41
- 50: '#faf5ff',
42
- 100: '#f3e8ff',
43
- 200: '#e9d5ff',
44
- 300: '#d8b4fe',
45
- 400: '#c084fc',
46
- 500: '#a855f7',
47
- 600: '#9333ea',
48
- 700: '#7c3aed',
49
- 800: '#6b21a8',
50
- 900: '#581c87',
51
- 950: '#3b0764',
52
- },
53
- info: {
54
- 50: '#ecfeff',
55
- 100: '#cffafe',
56
- 200: '#a5f3fc',
57
- 300: '#67e8f9',
58
- 400: '#22d3ee',
59
- 500: '#06b6d4',
60
- 600: '#0891b2',
61
- 700: '#0e7490',
62
- 800: '#155e75',
63
- 900: '#164e63',
64
- 950: '#083344',
65
- },
66
- warning: {
67
- 50: '#fff7ed',
68
- 100: '#ffedd5',
69
- 200: '#fed7aa',
70
- 300: '#fdba74',
71
- 400: '#fb923c',
72
- 500: '#f97316',
73
- 600: '#ea580c',
74
- 700: '#c2410c',
75
- 800: '#9a3412',
76
- 900: '#7c2d12',
77
- 950: '#431407',
78
- },
79
- danger: {
80
- 50: '#fef2f2',
81
- 100: '#fee2e2',
82
- 200: '#fecaca',
83
- 300: '#fca5a5',
84
- 400: '#f87171',
85
- 500: '#ef4444',
86
- 600: '#dc2626',
87
- 700: '#b91c1c',
88
- 800: '#991b1b',
89
- 900: '#7f1d1d',
90
- 950: '#450a0a',
91
- },
92
- success: {
93
- 50: '#ecfdf5',
94
- 100: '#d1fae5',
95
- 200: '#a7f3d0',
96
- 300: '#6ee7b7',
97
- 400: '#34d399',
98
- 500: '#10b981',
99
- 600: '#059669',
100
- 700: '#047857',
101
- 800: '#065f46',
102
- 900: '#064e3b',
103
- 950: '#022c22',
104
- },
105
- surface: {
106
- light: '#f8f8f8',
107
- dark: '#0a0a0a',
108
- card: {
109
- light: '#f1f5f9',
110
- dark: '#0f0f0f',
111
- }
112
- },
113
- },
114
- boxShadow: {
115
- 'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)',
116
- },
117
- },
118
- },
119
- plugins: [],
120
- }