Files
api/web/components/Activation/Modal.vue
Zack Spear d8a5b1711a feat(web): activation modal steps, updated copy (#1079)
* feat(stepper): add shadcn stepper components

* chore(serverState): remove partnerLogo property from server state configuration

* refactor(web): modal add subfooter slot

- adds ability to display content below the modal's content box

* feat(modal): add ActivationSteps component to subFooter slot in WelcomeModal and ActivationModal

* refactor: improve activation modal buttons responsiveness

* refactor: update activation flow messaging and UI

* feat: web/deploy-dev.sh add dynamic web component JS file whitelisting in auth-request.php

* fix: remove test UTM parameters from Unraid docs links in activation modal

* refactor: improve konami code handling and add type safety to activation steps

* chore: remove extra semicolon in serverState.ts

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-01-29 11:08:23 -08:00

128 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import { ArrowTopRightOnSquareIcon } from "@heroicons/vue/24/solid";
import { storeToRefs } from "pinia";
import type { ComposerTranslation } from "vue-i18n";
import { useActivationCodeStore } from "~/store/activationCode";
import { usePurchaseStore } from "~/store/purchase";
import type { ButtonProps } from "~/types/ui/button";
import ActivationPartnerLogo from "~/components/Activation/PartnerLogo.vue";
export interface Props {
t: ComposerTranslation;
}
const props = defineProps<Props>();
const activationCodeStore = useActivationCodeStore();
const { partnerLogo, showActivationModal } = storeToRefs(activationCodeStore);
const purchaseStore = usePurchaseStore();
const title = computed<string>(() => props.t("Let's activate your Unraid OS License"));
const description = computed<string>(() =>
props.t(
`On the following screen, your license will be activated. Youll then create an Unraid.net Account to manage your license going forward.`
)
);
const docsButtons = computed<ButtonProps[]>(() => {
return [
{
btnStyle: "underline",
external: true,
href: "https://docs.unraid.net/unraid-os/faq/licensing-faq/",
iconRight: ArrowTopRightOnSquareIcon,
size: "14px",
text: props.t("More about Licensing"),
},
{
btnStyle: "underline",
external: true,
href: "https://docs.unraid.net/account/",
iconRight: ArrowTopRightOnSquareIcon,
size: "14px",
text: props.t("More about Unraid.net Accounts"),
},
];
});
/**
* Listen for konami code sequence to close the modal
*/
const keySequence = [
"ArrowUp",
"ArrowUp",
"ArrowDown",
"ArrowDown",
"ArrowLeft",
"ArrowRight",
"ArrowLeft",
"ArrowRight",
"b",
"a",
];
let sequenceIndex = 0;
const handleKeydown = (event: KeyboardEvent) => {
if (event.key === keySequence[sequenceIndex]) {
sequenceIndex++;
} else {
sequenceIndex = 0;
}
if (sequenceIndex === keySequence.length) {
activationCodeStore.setActivationModalHidden(true);
window.location.href = "/Tools/Registration";
}
};
onMounted(() => {
window.addEventListener("keydown", handleKeydown);
});
onUnmounted(() => {
window.removeEventListener("keydown", handleKeydown);
});
</script>
<template>
<Modal
v-if="showActivationModal"
:t="t"
:open="showActivationModal"
:show-close-x="false"
:title="title"
:title-in-main="!!partnerLogo"
:description="description"
overlay-color="bg-background"
overlay-opacity="bg-opacity-100"
max-width="max-w-800px"
:modal-vertical-center="false"
:disable-shadow="true"
>
<template v-if="partnerLogo" #header>
<ActivationPartnerLogo />
</template>
<template #footer>
<div class="w-full flex gap-8px justify-center mx-auto">
<BrandButton
:text="t('Activate Now')"
:icon-right="ArrowTopRightOnSquareIcon"
@click="purchaseStore.activate"
/>
</div>
</template>
<template #subFooter>
<div class="flex flex-col gap-6">
<ActivationSteps :active-step="2" class="hidden sm:flex mt-6" />
<div class="flex flex-col sm:flex-row justify-center gap-4 mx-auto w-full">
<BrandButton v-for="button in docsButtons" :key="button.text" v-bind="button" />
</div>
</div>
</template>
</Modal>
</template>