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,
|
||||
mdiWindowClose,
|
||||
mdiWrench,
|
||||
mdiHandWaveOutline,
|
||||
} from "@mdi/js";
|
||||
|
||||
export const icons = {
|
||||
@@ -287,6 +288,7 @@ export const icons = {
|
||||
undo: mdiUndo,
|
||||
bread: mdiCookie,
|
||||
fileSign: mdiFileSign,
|
||||
wave: mdiHandWaveOutline,
|
||||
|
||||
// Crud
|
||||
backArrow: mdiArrowLeftBoldOutline,
|
||||
|
||||
@@ -19,35 +19,45 @@
|
||||
</v-toolbar>
|
||||
|
||||
<!-- 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-item
|
||||
:value="Pages.LANDING"
|
||||
:icon="$globals.icons.wave"
|
||||
:complete="currentPage > Pages.LANDING"
|
||||
:color="getStepperColor(currentPage, Pages.LANDING)"
|
||||
:title="$t('general.start')"
|
||||
/>
|
||||
<v-divider />
|
||||
<v-stepper-item
|
||||
:value="Pages.USER_INFO"
|
||||
:icon="$globals.icons.user"
|
||||
:complete="currentPage > Pages.USER_INFO"
|
||||
:color="getStepperColor(currentPage, Pages.USER_INFO)"
|
||||
:title="$t('user-registration.account-details')"
|
||||
/>
|
||||
<v-divider />
|
||||
<v-stepper-item
|
||||
:value="Pages.PAGE_2"
|
||||
:icon="$globals.icons.cog"
|
||||
:complete="currentPage > Pages.PAGE_2"
|
||||
:color="getStepperColor(currentPage, Pages.PAGE_2)"
|
||||
:title="$t('settings.site-settings')"
|
||||
/>
|
||||
<v-divider />
|
||||
<v-stepper-item
|
||||
:value="Pages.CONFIRM"
|
||||
:icon="$globals.icons.chefHat"
|
||||
:complete="currentPage > Pages.CONFIRM"
|
||||
:color="getStepperColor(currentPage, Pages.CONFIRM)"
|
||||
:title="$t('admin.maintenance.summary-title')"
|
||||
/>
|
||||
<v-divider />
|
||||
<v-stepper-item
|
||||
:value="Pages.END"
|
||||
:icon="$globals.icons.check"
|
||||
:complete="currentPage > Pages.END"
|
||||
:color="getStepperColor(currentPage, Pages.END)"
|
||||
:title="$t('admin.setup.setup-complete')"
|
||||
/>
|
||||
</v-stepper-header>
|
||||
@@ -82,6 +92,8 @@
|
||||
<BaseButton
|
||||
size="large"
|
||||
color="primary"
|
||||
class="px-10"
|
||||
rounded
|
||||
:icon="$globals.icons.translate"
|
||||
@click="langDialog = true"
|
||||
>
|
||||
@@ -95,6 +107,16 @@
|
||||
next-text="general.next"
|
||||
@click:next="onNext"
|
||||
>
|
||||
<template #next>
|
||||
<v-btn
|
||||
variant="flat"
|
||||
color="success"
|
||||
:disabled="isSubmitting"
|
||||
:loading="isSubmitting"
|
||||
:text="$t('general.next')"
|
||||
@click="onNext"
|
||||
/>
|
||||
</template>
|
||||
<template #prev />
|
||||
</v-stepper-actions>
|
||||
</v-stepper-window-item>
|
||||
@@ -107,10 +129,19 @@
|
||||
<v-stepper-actions
|
||||
:disabled="isSubmitting"
|
||||
prev-text="general.back"
|
||||
next-text="general.next"
|
||||
@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>
|
||||
|
||||
<!-- COMMON SETTINGS -->
|
||||
@@ -127,10 +158,19 @@
|
||||
<v-stepper-actions
|
||||
:disabled="isSubmitting"
|
||||
prev-text="general.back"
|
||||
next-text="general.next"
|
||||
@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>
|
||||
|
||||
<!-- CONFIRMATION -->
|
||||
@@ -177,35 +217,7 @@
|
||||
|
||||
<!-- END -->
|
||||
<v-stepper-window-item :value="Pages.END">
|
||||
<v-container max-width="880">
|
||||
<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>
|
||||
<EndPageContent />
|
||||
<v-stepper-actions
|
||||
:disabled="isSubmitting"
|
||||
prev-text="general.back"
|
||||
@@ -266,11 +278,21 @@ useSeoMeta({
|
||||
});
|
||||
|
||||
enum Pages {
|
||||
LANDING = 0,
|
||||
USER_INFO = 1,
|
||||
PAGE_2 = 2,
|
||||
CONFIRM = 3,
|
||||
END = 4,
|
||||
LANDING = 1,
|
||||
USER_INFO = 2,
|
||||
PAGE_2 = 3,
|
||||
CONFIRM = 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
|
||||
const currentPage = ref(Pages.LANDING);
|
||||
@@ -548,7 +534,7 @@ async function onFinish() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.icon-white {
|
||||
fill: white;
|
||||
}
|
||||
@@ -575,4 +561,18 @@ async function onFinish() {
|
||||
.bg-off-white {
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user