mirror of
https://github.com/unraid/api.git
synced 2026-01-05 16:09:49 -06:00
* 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>
128 lines
3.3 KiB
Vue
128 lines
3.3 KiB
Vue
<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. You’ll 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>
|