mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-06 10:25:18 -05:00
feat: Improve startup workflow UI (#6342)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
This commit is contained in:
121
frontend/components/Domain/Admin/Setup/EndPageContent.vue
Normal file
121
frontend/components/Domain/Admin/Setup/EndPageContent.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<v-container max-width="880" class="end-page-content">
|
||||||
|
<div class="d-flex flex-column ga-6">
|
||||||
|
<div>
|
||||||
|
<v-card-title class="text-h4 justify-center">
|
||||||
|
{{ $t('admin.setup.setup-complete') }}
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-subtitle class="justify-center">
|
||||||
|
{{ $t('admin.setup.here-are-a-few-things-to-help-you-get-started') }}
|
||||||
|
</v-card-subtitle>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="section, idx in sections"
|
||||||
|
:key="idx"
|
||||||
|
class="d-flex flex-column ga-3"
|
||||||
|
>
|
||||||
|
<v-card-title class="text-h6 pl-0">
|
||||||
|
{{ section.title }}
|
||||||
|
</v-card-title>
|
||||||
|
<div class="sections d-flex flex-column ga-2">
|
||||||
|
<v-card
|
||||||
|
v-for="link, linkIdx in section.links"
|
||||||
|
:key="linkIdx"
|
||||||
|
clas="link-card"
|
||||||
|
:href="link.to"
|
||||||
|
:title="link.text"
|
||||||
|
:subtitle="link.description"
|
||||||
|
:append-icon="$globals.icons.chevronRight"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<v-avatar :icon="link.icon || undefined" variant="tonal" :color="section.color" />
|
||||||
|
</template>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default defineNuxtComponent({
|
||||||
|
setup() {
|
||||||
|
const i18n = useI18n();
|
||||||
|
const $auth = useMealieAuth();
|
||||||
|
const groupSlug = computed(() => $auth.user.value?.groupSlug);
|
||||||
|
const { $globals } = useNuxtApp();
|
||||||
|
|
||||||
|
const sections = ref([
|
||||||
|
{
|
||||||
|
title: i18n.t("profile.data-migrations"),
|
||||||
|
color: "info",
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
icon: $globals.icons.backupRestore,
|
||||||
|
to: "/admin/backups",
|
||||||
|
text: i18n.t("settings.backup.backup-restore"),
|
||||||
|
description: i18n.t("admin.setup.restore-from-v1-backup"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: $globals.icons.import,
|
||||||
|
to: "/group/migrations",
|
||||||
|
text: i18n.t("migration.recipe-migration"),
|
||||||
|
description: i18n.t("migration.coming-from-another-application-or-an-even-older-version-of-mealie"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t("recipe.create-recipes"),
|
||||||
|
color: "success",
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
icon: $globals.icons.createAlt,
|
||||||
|
to: computed(() => `/g/${groupSlug.value || ""}/r/create/new`),
|
||||||
|
text: i18n.t("recipe.create-recipe"),
|
||||||
|
description: i18n.t("recipe.create-recipe-description"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: $globals.icons.link,
|
||||||
|
to: computed(() => `/g/${groupSlug.value || ""}/r/create/url`),
|
||||||
|
text: i18n.t("recipe.import-with-url"),
|
||||||
|
description: i18n.t("recipe.scrape-recipe-description"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t("user.manage-users"),
|
||||||
|
color: "primary",
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
icon: $globals.icons.group,
|
||||||
|
to: "/admin/manage/users",
|
||||||
|
text: i18n.t("user.manage-users"),
|
||||||
|
description: i18n.t("user.manage-users-description"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: $globals.icons.user,
|
||||||
|
to: "/user/profile",
|
||||||
|
text: i18n.t("profile.manage-user-profile"),
|
||||||
|
description: i18n.t("admin.setup.manage-profile-or-get-invite-link"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
return { sections };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.v-container {
|
||||||
|
.v-card-title,
|
||||||
|
.v-card-subtitle {
|
||||||
|
padding: 0;
|
||||||
|
white-space: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-card-item {
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -154,6 +154,7 @@ import {
|
|||||||
mdiWebhook,
|
mdiWebhook,
|
||||||
mdiWindowClose,
|
mdiWindowClose,
|
||||||
mdiWrench,
|
mdiWrench,
|
||||||
|
mdiHandWaveOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
|
|
||||||
export const icons = {
|
export const icons = {
|
||||||
@@ -287,6 +288,7 @@ export const icons = {
|
|||||||
undo: mdiUndo,
|
undo: mdiUndo,
|
||||||
bread: mdiCookie,
|
bread: mdiCookie,
|
||||||
fileSign: mdiFileSign,
|
fileSign: mdiFileSign,
|
||||||
|
wave: mdiHandWaveOutline,
|
||||||
|
|
||||||
// Crud
|
// Crud
|
||||||
backArrow: mdiArrowLeftBoldOutline,
|
backArrow: mdiArrowLeftBoldOutline,
|
||||||
|
|||||||
@@ -19,35 +19,45 @@
|
|||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
|
||||||
<!-- Stepper Wizard -->
|
<!-- Stepper Wizard -->
|
||||||
<v-stepper v-model="currentPage" mobile-breakpoint="sm">
|
<v-stepper v-model="currentPage" mobile-breakpoint="sm" alt-labels>
|
||||||
<v-stepper-header>
|
<v-stepper-header>
|
||||||
<v-stepper-item
|
<v-stepper-item
|
||||||
:value="Pages.LANDING"
|
:value="Pages.LANDING"
|
||||||
|
:icon="$globals.icons.wave"
|
||||||
:complete="currentPage > Pages.LANDING"
|
:complete="currentPage > Pages.LANDING"
|
||||||
|
:color="getStepperColor(currentPage, Pages.LANDING)"
|
||||||
:title="$t('general.start')"
|
:title="$t('general.start')"
|
||||||
/>
|
/>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-stepper-item
|
<v-stepper-item
|
||||||
:value="Pages.USER_INFO"
|
:value="Pages.USER_INFO"
|
||||||
|
:icon="$globals.icons.user"
|
||||||
:complete="currentPage > Pages.USER_INFO"
|
:complete="currentPage > Pages.USER_INFO"
|
||||||
|
:color="getStepperColor(currentPage, Pages.USER_INFO)"
|
||||||
:title="$t('user-registration.account-details')"
|
:title="$t('user-registration.account-details')"
|
||||||
/>
|
/>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-stepper-item
|
<v-stepper-item
|
||||||
:value="Pages.PAGE_2"
|
:value="Pages.PAGE_2"
|
||||||
|
:icon="$globals.icons.cog"
|
||||||
:complete="currentPage > Pages.PAGE_2"
|
:complete="currentPage > Pages.PAGE_2"
|
||||||
|
:color="getStepperColor(currentPage, Pages.PAGE_2)"
|
||||||
:title="$t('settings.site-settings')"
|
:title="$t('settings.site-settings')"
|
||||||
/>
|
/>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-stepper-item
|
<v-stepper-item
|
||||||
:value="Pages.CONFIRM"
|
:value="Pages.CONFIRM"
|
||||||
|
:icon="$globals.icons.chefHat"
|
||||||
:complete="currentPage > Pages.CONFIRM"
|
:complete="currentPage > Pages.CONFIRM"
|
||||||
|
:color="getStepperColor(currentPage, Pages.CONFIRM)"
|
||||||
:title="$t('admin.maintenance.summary-title')"
|
:title="$t('admin.maintenance.summary-title')"
|
||||||
/>
|
/>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-stepper-item
|
<v-stepper-item
|
||||||
:value="Pages.END"
|
:value="Pages.END"
|
||||||
|
:icon="$globals.icons.check"
|
||||||
:complete="currentPage > Pages.END"
|
:complete="currentPage > Pages.END"
|
||||||
|
:color="getStepperColor(currentPage, Pages.END)"
|
||||||
:title="$t('admin.setup.setup-complete')"
|
:title="$t('admin.setup.setup-complete')"
|
||||||
/>
|
/>
|
||||||
</v-stepper-header>
|
</v-stepper-header>
|
||||||
@@ -82,6 +92,8 @@
|
|||||||
<BaseButton
|
<BaseButton
|
||||||
size="large"
|
size="large"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
class="px-10"
|
||||||
|
rounded
|
||||||
:icon="$globals.icons.translate"
|
:icon="$globals.icons.translate"
|
||||||
@click="langDialog = true"
|
@click="langDialog = true"
|
||||||
>
|
>
|
||||||
@@ -95,6 +107,16 @@
|
|||||||
next-text="general.next"
|
next-text="general.next"
|
||||||
@click:next="onNext"
|
@click:next="onNext"
|
||||||
>
|
>
|
||||||
|
<template #next>
|
||||||
|
<v-btn
|
||||||
|
variant="flat"
|
||||||
|
color="success"
|
||||||
|
:disabled="isSubmitting"
|
||||||
|
:loading="isSubmitting"
|
||||||
|
:text="$t('general.next')"
|
||||||
|
@click="onNext"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #prev />
|
<template #prev />
|
||||||
</v-stepper-actions>
|
</v-stepper-actions>
|
||||||
</v-stepper-window-item>
|
</v-stepper-window-item>
|
||||||
@@ -107,10 +129,19 @@
|
|||||||
<v-stepper-actions
|
<v-stepper-actions
|
||||||
:disabled="isSubmitting"
|
:disabled="isSubmitting"
|
||||||
prev-text="general.back"
|
prev-text="general.back"
|
||||||
next-text="general.next"
|
|
||||||
@click:prev="onPrev"
|
@click:prev="onPrev"
|
||||||
@click:next="onNext"
|
>
|
||||||
|
<template #next>
|
||||||
|
<v-btn
|
||||||
|
variant="flat"
|
||||||
|
color="success"
|
||||||
|
:disabled="isSubmitting"
|
||||||
|
:loading="isSubmitting"
|
||||||
|
:text="$t('general.next')"
|
||||||
|
@click="onNext"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
</v-stepper-actions>
|
||||||
</v-stepper-window-item>
|
</v-stepper-window-item>
|
||||||
|
|
||||||
<!-- COMMON SETTINGS -->
|
<!-- COMMON SETTINGS -->
|
||||||
@@ -127,10 +158,19 @@
|
|||||||
<v-stepper-actions
|
<v-stepper-actions
|
||||||
:disabled="isSubmitting"
|
:disabled="isSubmitting"
|
||||||
prev-text="general.back"
|
prev-text="general.back"
|
||||||
next-text="general.next"
|
|
||||||
@click:prev="onPrev"
|
@click:prev="onPrev"
|
||||||
@click:next="onNext"
|
>
|
||||||
|
<template #next>
|
||||||
|
<v-btn
|
||||||
|
variant="flat"
|
||||||
|
color="success"
|
||||||
|
:disabled="isSubmitting"
|
||||||
|
:loading="isSubmitting"
|
||||||
|
:text="$t('general.next')"
|
||||||
|
@click="onNext"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
</v-stepper-actions>
|
||||||
</v-stepper-window-item>
|
</v-stepper-window-item>
|
||||||
|
|
||||||
<!-- CONFIRMATION -->
|
<!-- CONFIRMATION -->
|
||||||
@@ -177,35 +217,7 @@
|
|||||||
|
|
||||||
<!-- END -->
|
<!-- END -->
|
||||||
<v-stepper-window-item :value="Pages.END">
|
<v-stepper-window-item :value="Pages.END">
|
||||||
<v-container max-width="880">
|
<EndPageContent />
|
||||||
<v-card-title class="text-h4 justify-center">
|
|
||||||
{{ $t('admin.setup.setup-complete') }}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-title class="text-h6 justify-center">
|
|
||||||
{{ $t('admin.setup.here-are-a-few-things-to-help-you-get-started') }}
|
|
||||||
</v-card-title>
|
|
||||||
<div
|
|
||||||
v-for="link, idx in setupCompleteLinks"
|
|
||||||
:key="idx"
|
|
||||||
class="px-4 pt-4"
|
|
||||||
>
|
|
||||||
<div v-if="link.section">
|
|
||||||
<v-divider v-if="idx" />
|
|
||||||
<v-card-text class="headline pl-0">
|
|
||||||
{{ link.section }}
|
|
||||||
</v-card-text>
|
|
||||||
</div>
|
|
||||||
<v-btn
|
|
||||||
:to="link.to"
|
|
||||||
color="info"
|
|
||||||
>
|
|
||||||
{{ link.text }}
|
|
||||||
</v-btn>
|
|
||||||
<v-card-text class="subtitle px-0 py-2">
|
|
||||||
{{ link.description }}
|
|
||||||
</v-card-text>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
|
||||||
<v-stepper-actions
|
<v-stepper-actions
|
||||||
:disabled="isSubmitting"
|
:disabled="isSubmitting"
|
||||||
prev-text="general.back"
|
prev-text="general.back"
|
||||||
@@ -266,11 +278,21 @@ useSeoMeta({
|
|||||||
});
|
});
|
||||||
|
|
||||||
enum Pages {
|
enum Pages {
|
||||||
LANDING = 0,
|
LANDING = 1,
|
||||||
USER_INFO = 1,
|
USER_INFO = 2,
|
||||||
PAGE_2 = 2,
|
PAGE_2 = 3,
|
||||||
CONFIRM = 3,
|
CONFIRM = 4,
|
||||||
END = 4,
|
END = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStepperColor(currentPage: Pages, page: Pages) {
|
||||||
|
if (currentPage == page) {
|
||||||
|
return "info";
|
||||||
|
}
|
||||||
|
if (currentPage > page) {
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -317,42 +339,6 @@ const confirmationData = computed(() => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
const setupCompleteLinks = ref([
|
|
||||||
{
|
|
||||||
section: i18n.t("profile.data-migrations"),
|
|
||||||
to: "/admin/backups",
|
|
||||||
text: i18n.t("settings.backup.backup-restore"),
|
|
||||||
description: i18n.t("admin.setup.restore-from-v1-backup"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: "/group/migrations",
|
|
||||||
text: i18n.t("migration.recipe-migration"),
|
|
||||||
description: i18n.t("migration.coming-from-another-application-or-an-even-older-version-of-mealie"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
section: i18n.t("recipe.create-recipes"),
|
|
||||||
to: computed(() => `/g/${groupSlug.value || ""}/r/create/new`),
|
|
||||||
text: i18n.t("recipe.create-recipe"),
|
|
||||||
description: i18n.t("recipe.create-recipe-description"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: computed(() => `/g/${groupSlug.value || ""}/r/create/url`),
|
|
||||||
text: i18n.t("recipe.import-with-url"),
|
|
||||||
description: i18n.t("recipe.scrape-recipe-description"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
section: i18n.t("user.manage-users"),
|
|
||||||
to: "/admin/manage/users",
|
|
||||||
text: i18n.t("user.manage-users"),
|
|
||||||
description: i18n.t("user.manage-users-description"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: "/user/profile",
|
|
||||||
text: i18n.t("profile.manage-user-profile"),
|
|
||||||
description: i18n.t("admin.setup.manage-profile-or-get-invite-link"),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
// Page Navigation
|
// Page Navigation
|
||||||
const currentPage = ref(Pages.LANDING);
|
const currentPage = ref(Pages.LANDING);
|
||||||
@@ -548,7 +534,7 @@ async function onFinish() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
.icon-white {
|
.icon-white {
|
||||||
fill: white;
|
fill: white;
|
||||||
}
|
}
|
||||||
@@ -575,4 +561,18 @@ async function onFinish() {
|
|||||||
.bg-off-white {
|
.bg-off-white {
|
||||||
background: #f5f8fa;
|
background: #f5f8fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-stepper-item__avatar.v-avatar.v-stepper-item__avatar.v-avatar {
|
||||||
|
width: 3rem !important; /** Override inline style :( */
|
||||||
|
height: 3rem !important; /** Override inline style :( */
|
||||||
|
margin-inline-end: 0; /** reset weird margin */
|
||||||
|
|
||||||
|
.v-icon {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-stepper--alt-labels .v-stepper-header .v-divider {
|
||||||
|
margin: 48px -42px 0 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user