feat: add design persistence functionality with Auth0 and Supabase integration

- Implemented `useDesignPersistence` composable for managing design records.
- Enhanced `useSlipmatDesigner` to support loading designs from JSON.
- Created global authentication middleware for route protection.
- Added Supabase client plugin for database interactions.
- Developed API endpoints for fetching, saving, and retrieving designs.
- Introduced utility functions for Auth0 token verification and Supabase client retrieval.
- Updated Nuxt configuration to include Auth0 and Supabase environment variables.
- Added necessary dependencies for Auth0 and Supabase.
- Enhanced TypeScript configuration for improved type support.
This commit is contained in:
Frank John Begornia
2025-11-07 00:01:52 +08:00
parent e2955debb7
commit 4d91925fad
20 changed files with 1242 additions and 19 deletions

44
middleware/auth.global.ts Normal file
View File

@@ -0,0 +1,44 @@
import { useAuth0 } from "@auth0/auth0-vue";
import { watch } from "vue";
import { abortNavigation, defineNuxtRouteMiddleware } from "nuxt/app";
const waitUntilLoaded = async (isLoading: { value: boolean }) => {
if (!isLoading.value) {
return;
}
await new Promise<void>((resolve) => {
const stop = watch(
() => isLoading.value,
(value) => {
if (!value) {
stop();
resolve();
}
}
);
});
};
export default defineNuxtRouteMiddleware(async (to) => {
if (process.server) {
return;
}
if (to.path.startsWith("/auth/callback")) {
return;
}
const auth0 = useAuth0();
await waitUntilLoaded(auth0.isLoading);
if (auth0.isAuthenticated.value) {
return;
}
await auth0.loginWithRedirect({
appState: { target: to.fullPath },
});
return abortNavigation();
});

44
middleware/auth.ts Normal file
View File

@@ -0,0 +1,44 @@
import { useAuth0 } from "@auth0/auth0-vue";
import { watch } from "vue";
import { abortNavigation } from "#app";
const waitUntilLoaded = async (isLoading: { value: boolean }) => {
if (!isLoading.value) {
return;
}
await new Promise<void>((resolve) => {
const stop = watch(
() => isLoading.value,
(value) => {
if (!value) {
stop();
resolve();
}
}
);
});
};
export default defineNuxtRouteMiddleware(async (to) => {
if (import.meta.server) {
return;
}
if (to.path.startsWith("/auth/callback")) {
return;
}
const auth0 = useAuth0();
await waitUntilLoaded(auth0.isLoading);
if (auth0.isAuthenticated.value) {
return;
}
await auth0.loginWithRedirect({
appState: { target: to.fullPath },
});
return abortNavigation();
});