mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-02 20:15:24 +02:00
feat: Migrate to Nuxt 3 framework (#5184)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com> Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
parent
89ab7fac25
commit
c24d532608
403 changed files with 23959 additions and 19557 deletions
44
frontend/plugins/axios.ts
Normal file
44
frontend/plugins/axios.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import axios from "axios";
|
||||
import { alert } from "~/composables/use-toast";
|
||||
|
||||
export default defineNuxtPlugin(() => {
|
||||
const tokenName = useRuntimeConfig().public.AUTH_TOKEN;
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: "/", // api calls already pass with /api
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer " + useCookie(tokenName).value,
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
// Add request interceptor
|
||||
axiosInstance.interceptors.request.use(
|
||||
(config) => {
|
||||
// You can add auth tokens or other headers here
|
||||
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);
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
provide: {
|
||||
axios: axiosInstance,
|
||||
},
|
||||
};
|
||||
});
|
|
@ -1,13 +1,20 @@
|
|||
import { Plugin } from "@nuxt/types"
|
||||
import { useDark } from "@vueuse/core";
|
||||
|
||||
const darkModePlugin: Plugin = ({ $vuetify }, _) => {
|
||||
const isDark = useDark();
|
||||
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";
|
||||
},
|
||||
});
|
||||
|
||||
// Vuetify metadata is bugged and doesn't render dark mode fully when called immediately
|
||||
// Adding a delay fixes this problem
|
||||
// https://stackoverflow.com/questions/69399797/vuetify-darkmode-colors-wrong-after-page-reload
|
||||
setTimeout(() => { $vuetify.theme.dark = isDark.value; }, 200);
|
||||
};
|
||||
nuxtApp.hook("vuetify:ready", (vuetify) => {
|
||||
vuetify.theme.global.name.value = isDark.value ? "dark" : "light";
|
||||
});
|
||||
|
||||
export default darkModePlugin;
|
||||
return {
|
||||
provide: {},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,37 +1,11 @@
|
|||
import { Plugin } from "@nuxt/types";
|
||||
import { Auth as NuxtAuth } from "@nuxtjs/auth-next";
|
||||
import { Framework } from "vuetify";
|
||||
import { UserOut } from "~/lib/api/types/user";
|
||||
import { icons } from "~/lib/icons";
|
||||
import { Icon } from "~/lib/icons/icon-type";
|
||||
|
||||
interface Globals {
|
||||
icons: Icon;
|
||||
}
|
||||
|
||||
declare module "vue/types/vue" {
|
||||
interface Vue {
|
||||
$globals: Globals;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@nuxt/types" {
|
||||
// @ts-ignore https://github.com/nuxt-community/auth-module/issues/1097#issuecomment-840249428
|
||||
interface Auth extends NuxtAuth {
|
||||
user: UserOut | null;
|
||||
}
|
||||
|
||||
interface Context {
|
||||
$globals: Globals;
|
||||
$vuetify: Framework;
|
||||
$auth: Auth;
|
||||
}
|
||||
}
|
||||
|
||||
const globalsPlugin: Plugin = (_, inject) => {
|
||||
inject("globals", {
|
||||
icons,
|
||||
});
|
||||
};
|
||||
|
||||
export default globalsPlugin;
|
||||
export default defineNuxtPlugin(() => {
|
||||
return {
|
||||
provide: {
|
||||
globals: {
|
||||
icons,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { Plugin } from "@nuxt/types";
|
||||
|
||||
export interface ThemeConfig {
|
||||
lightPrimary: string;
|
||||
lightAccent: string;
|
||||
|
@ -26,39 +24,53 @@ async function fetchTheme(): Promise<ThemeConfig | undefined> {
|
|||
const response = await fetch(route);
|
||||
const data = await response.json();
|
||||
return data as ThemeConfig;
|
||||
} catch (error) {
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const themePlugin: Plugin = async ({ $vuetify, $config }) => {
|
||||
let theme = __cachedTheme;
|
||||
if (!theme) {
|
||||
theme = await fetchTheme();
|
||||
__cachedTheme = theme;
|
||||
}
|
||||
|
||||
if (theme) {
|
||||
$vuetify.theme.themes.light.primary = theme.lightPrimary;
|
||||
$vuetify.theme.themes.light.accent = theme.lightAccent;
|
||||
$vuetify.theme.themes.light.secondary = theme.lightSecondary;
|
||||
$vuetify.theme.themes.light.success = theme.lightSuccess;
|
||||
$vuetify.theme.themes.light.info = theme.lightInfo;
|
||||
$vuetify.theme.themes.light.warning = theme.lightWarning;
|
||||
$vuetify.theme.themes.light.error = theme.lightError;
|
||||
|
||||
$vuetify.theme.themes.dark.primary = theme.darkPrimary;
|
||||
$vuetify.theme.themes.dark.accent = theme.darkAccent;
|
||||
$vuetify.theme.themes.dark.secondary = theme.darkSecondary;
|
||||
$vuetify.theme.themes.dark.success = theme.darkSuccess;
|
||||
$vuetify.theme.themes.dark.info = theme.darkInfo;
|
||||
$vuetify.theme.themes.dark.warning = theme.darkWarning;
|
||||
$vuetify.theme.themes.dark.error = theme.darkError;
|
||||
}
|
||||
|
||||
if ($config.useDark) {
|
||||
$vuetify.theme.dark = true;
|
||||
}
|
||||
};
|
||||
|
||||
export default themePlugin;
|
||||
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: {
|
||||
dark: {
|
||||
dark: true,
|
||||
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",
|
||||
background: "#1E1E1E",
|
||||
},
|
||||
},
|
||||
light: {
|
||||
dark: false,
|
||||
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",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import { Plugin } from "@nuxt/types";
|
||||
import type { NuxtAxiosInstance } from "@nuxtjs/axios";
|
||||
import { alert } from "~/composables/use-toast";
|
||||
|
||||
const toastPlugin: Plugin = ({ $axios }: { $axios: NuxtAxiosInstance }) => {
|
||||
$axios.onResponse((response) => {
|
||||
if (response?.data?.message) {
|
||||
alert.info(response.data.message as string);
|
||||
}
|
||||
});
|
||||
$axios.onError((error) => {
|
||||
if (error.response?.data?.detail?.message) {
|
||||
alert.error(error.response.data.detail.message as string);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default toastPlugin;
|
Loading…
Add table
Add a link
Reference in a new issue