chore: Nuxt 4 upgrade (#7426)

This commit is contained in:
Kuchenpirat
2026-04-08 17:25:41 +02:00
committed by GitHub
parent 70a251a331
commit d3e41582ae
561 changed files with 1840 additions and 2750 deletions

View File

@@ -0,0 +1,14 @@
import axios from "axios";
import type { AppInfo } from "~/lib/api/types/admin";
export default defineNuxtPlugin({
async setup() {
const { data } = await axios.get<AppInfo>("/api/app/about");
return {
provide: {
appInfo: data,
},
};
},
});

View File

@@ -0,0 +1,58 @@
import axios from "axios";
import { alert } from "~/composables/use-toast";
export default defineNuxtPlugin(() => {
const tokenName = useRuntimeConfig().public.AUTH_TOKEN;
const axiosInstance = axios.create({
// timeout removed to allow backend to handle timeouts
baseURL: "/", // api calls already pass with /api
withCredentials: true,
});
axiosInstance.interceptors.request.use(
(config) => {
const token = useCookie(tokenName).value;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
},
);
// Add response interceptor
axiosInstance.interceptors.response.use(
(response) => {
if (response?.data?.message) alert.info(response.data.message as string);
return response;
},
(error) => {
if (error?.response?.data?.detail?.message) {
alert.error(error.response.data.detail.message as string);
};
// If we receive a 401 Unauthorized response, clear the token cookie and redirect to login
if (error?.response?.status === 401) {
// If tokenCookie is not set, we may just be an unauthenticated user using the wrong API, so don't redirect
const tokenCookie = useCookie(tokenName);
if (tokenCookie.value) {
tokenCookie.value = null;
// Disable beforeunload warnings to prevent "Are you sure you want to leave?" popups
window.onbeforeunload = null;
window.location.href = "/login";
}
}
return Promise.reject(error);
},
);
return {
provide: {
axios: axiosInstance,
},
};
});

View File

@@ -0,0 +1,20 @@
import { useDark } from "@vueuse/core";
export default defineNuxtPlugin((nuxtApp) => {
const isDark = useDark({
onChanged: (v) => {
console.log(`changing theme to ${v ? "dark" : "light"} using @vueuse/useDark`);
const $vuetify = nuxtApp.vueApp.$nuxt.$vuetify;
if ($vuetify)
$vuetify.theme.global.name.value = v ? "dark" : "light";
},
});
nuxtApp.hook("vuetify:ready", (vuetify) => {
vuetify.theme.global.name.value = isDark.value ? "dark" : "light";
});
return {
provide: {},
};
});

View File

@@ -0,0 +1,11 @@
import { icons } from "~/lib/icons";
export default defineNuxtPlugin(() => {
return {
provide: {
globals: {
icons,
},
},
};
});

View File

@@ -0,0 +1,9 @@
export default defineNuxtPlugin({
async setup() {
const auth = useAuthBackend();
console.debug("Initializing auth plugin");
await auth.getSession();
console.debug("Auth plugin initialized");
},
});

View File

@@ -0,0 +1,76 @@
export interface ThemeConfig {
lightPrimary: string;
lightAccent: string;
lightSecondary: string;
lightSuccess: string;
lightInfo: string;
lightWarning: string;
lightError: string;
darkPrimary: string;
darkAccent: string;
darkSecondary: string;
darkSuccess: string;
darkInfo: string;
darkWarning: string;
darkError: string;
}
let __cachedTheme: ThemeConfig | undefined;
async function fetchTheme(): Promise<ThemeConfig | undefined> {
const route = "/api/app/about/theme";
try {
const response = await fetch(route);
const data = await response.json();
return data as ThemeConfig;
}
catch {
return undefined;
}
}
export default defineNuxtPlugin(async (nuxtApp) => {
nuxtApp.hook("vuetify:before-create", async ({ vuetifyOptions }) => {
let theme = __cachedTheme;
if (!theme) {
theme = await fetchTheme();
__cachedTheme = theme;
}
vuetifyOptions.theme = {
defaultTheme: nuxtApp.$config.public.useDark ? "dark" : "light",
variations: {
colors: ["primary", "accent", "secondary", "success", "info", "warning", "error", "background"],
lighten: 3,
darken: 3,
},
themes: {
light: {
dark: false,
colors: {
primary: theme?.lightPrimary ?? "#E58325",
accent: theme?.lightAccent ?? "#007A99",
secondary: theme?.lightSecondary ?? "#973542",
success: theme?.lightSuccess ?? "#43A047",
info: theme?.lightInfo ?? "#1976d2",
warning: theme?.lightWarning ?? "#FF6D00",
error: theme?.lightError ?? "#EF5350",
},
},
dark: {
dark: true,
colors: {
primary: theme?.darkPrimary ?? "#E58325",
accent: theme?.darkAccent ?? "#007A99",
secondary: theme?.darkSecondary ?? "#973542",
success: theme?.darkSuccess ?? "#43A047",
info: theme?.darkInfo ?? "#1976d2",
warning: theme?.darkWarning ?? "#FF6D00",
error: theme?.darkError ?? "#EF5350",
background: "#1E1E1E",
},
},
},
};
});
});