Skip to content

Commit 7ec1b08

Browse files
Merge pull request #5 from CarterPerez-dev/chore/updates
Chore/updates
2 parents ac0a32e + 6e353d1 commit 7ec1b08

File tree

5 files changed

+196
-1
lines changed

5 files changed

+196
-1
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ dist/
1919
downloads/
2020
eggs/
2121
.eggs/
22-
lib/
2322
lib64/
2423
parts/
2524
sdist/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
©AngelaMos | 2025 | CarterPerez-dev
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// ===================
2+
// © AngelaMos | 2025
3+
// auth.store.ts
4+
// ===================
5+
6+
import { create } from 'zustand'
7+
import { devtools, persist } from 'zustand/middleware'
8+
import { type UserResponse, UserRole } from '@/api/types'
9+
import { STORAGE_KEYS } from '@/config'
10+
11+
interface AuthState {
12+
user: UserResponse | null
13+
accessToken: string | null
14+
isAuthenticated: boolean
15+
isLoading: boolean
16+
}
17+
18+
interface AuthActions {
19+
login: (user: UserResponse, accessToken: string) => void
20+
logout: () => void
21+
setLoading: (loading: boolean) => void
22+
setAccessToken: (token: string | null) => void
23+
updateUser: (updates: Partial<UserResponse>) => void
24+
}
25+
26+
type AuthStore = AuthState & AuthActions
27+
28+
export const useAuthStore = create<AuthStore>()(
29+
devtools(
30+
persist(
31+
(set) => ({
32+
user: null,
33+
accessToken: null,
34+
isAuthenticated: false,
35+
isLoading: false,
36+
37+
login: (user, accessToken) =>
38+
set(
39+
{
40+
user,
41+
accessToken,
42+
isAuthenticated: true,
43+
isLoading: false,
44+
},
45+
false,
46+
'auth/login'
47+
),
48+
49+
logout: () =>
50+
set(
51+
{
52+
user: null,
53+
accessToken: null,
54+
isAuthenticated: false,
55+
isLoading: false,
56+
},
57+
false,
58+
'auth/logout'
59+
),
60+
61+
setLoading: (loading) =>
62+
set({ isLoading: loading }, false, 'auth/setLoading'),
63+
64+
setAccessToken: (token) =>
65+
set({ accessToken: token }, false, 'auth/setAccessToken'),
66+
67+
updateUser: (updates) =>
68+
set(
69+
(state) => ({
70+
user: state.user !== null ? { ...state.user, ...updates } : null,
71+
}),
72+
false,
73+
'auth/updateUser'
74+
),
75+
}),
76+
{
77+
name: STORAGE_KEYS.AUTH,
78+
partialize: (state) => ({
79+
user: state.user,
80+
isAuthenticated: state.isAuthenticated,
81+
}),
82+
}
83+
),
84+
{ name: 'AuthStore' }
85+
)
86+
)
87+
88+
export const useUser = (): UserResponse | null => useAuthStore((s) => s.user)
89+
export const useIsAuthenticated = (): boolean =>
90+
useAuthStore((s) => s.isAuthenticated)
91+
export const useIsAuthLoading = (): boolean => useAuthStore((s) => s.isLoading)
92+
export const useAccessToken = (): string | null =>
93+
useAuthStore((s) => s.accessToken)
94+
95+
export const useHasRole = (role: UserRole): boolean => {
96+
const user = useAuthStore((s) => s.user)
97+
return user !== null && user.role === role
98+
}
99+
100+
export const useIsAdmin = (): boolean => {
101+
const user = useAuthStore((s) => s.user)
102+
return user !== null && user.role === UserRole.ADMIN
103+
}
104+
105+
export { UserRole }

frontend/src/core/lib/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// ===================
2+
// © AngelaMos | 2025
3+
// index.ts
4+
// ===================
5+
6+
export * from './auth.store'
7+
export * from './ui.store'

frontend/src/core/lib/ui.store.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* ©AngelaMos | 2025
3+
* ui.store.ts
4+
*/
5+
6+
import { create } from 'zustand'
7+
import { devtools, persist } from 'zustand/middleware'
8+
9+
type Theme = 'light' | 'dark' | 'system'
10+
11+
interface UIState {
12+
theme: Theme
13+
sidebarOpen: boolean
14+
sidebarCollapsed: boolean
15+
setTheme: (theme: Theme) => void
16+
toggleSidebar: () => void
17+
setSidebarOpen: (open: boolean) => void
18+
toggleSidebarCollapsed: () => void
19+
}
20+
21+
export const useUIStore = create<UIState>()(
22+
devtools(
23+
persist(
24+
(set) => ({
25+
theme: 'dark',
26+
sidebarOpen: false,
27+
sidebarCollapsed: false,
28+
29+
setTheme: (theme) => set({ theme }, false, 'ui/setTheme'),
30+
31+
toggleSidebar: () =>
32+
set(
33+
(state) => ({ sidebarOpen: !state.sidebarOpen }),
34+
false,
35+
'ui/toggleSidebar'
36+
),
37+
38+
setSidebarOpen: (open) =>
39+
set({ sidebarOpen: open }, false, 'ui/setSidebarOpen'),
40+
41+
toggleSidebarCollapsed: () =>
42+
set(
43+
(state) => ({ sidebarCollapsed: !state.sidebarCollapsed }),
44+
false,
45+
'ui/toggleSidebarCollapsed'
46+
),
47+
}),
48+
{
49+
name: 'ui-storage',
50+
partialize: (state) => ({
51+
theme: state.theme,
52+
sidebarCollapsed: state.sidebarCollapsed,
53+
}),
54+
}
55+
),
56+
{ name: 'UIStore' }
57+
)
58+
)
59+
60+
export const useTheme = (): Theme => useUIStore((s) => s.theme)
61+
export const useSidebarOpen = (): boolean => useUIStore((s) => s.sidebarOpen)
62+
export const useSidebarCollapsed = (): boolean =>
63+
useUIStore((s) => s.sidebarCollapsed)

0 commit comments

Comments
 (0)