2024-12-15 23:23:20 +05:30
|
|
|
import { useEffect, useMemo, useState } from "react";
|
2024-12-15 14:25:18 +05:30
|
|
|
import {
|
|
|
|
Dialog,
|
|
|
|
DialogContent,
|
|
|
|
DialogDescription,
|
|
|
|
DialogFooter,
|
|
|
|
DialogHeader,
|
|
|
|
DialogTitle,
|
|
|
|
} from "../ui/dialog";
|
2024-12-15 22:32:07 +05:30
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
import SelectTheme from "@/components/sidebar/settings-tab/select-theme";
|
|
|
|
import {
|
|
|
|
autoUpdateAtom,
|
|
|
|
enableContributionAtom,
|
|
|
|
} from "@/atoms/user-settings-atom";
|
|
|
|
import { useAtom } from "jotai";
|
2024-12-15 23:23:20 +05:30
|
|
|
import useTranslation from "../hooks/use-translation";
|
2024-12-15 14:25:18 +05:30
|
|
|
|
|
|
|
type OnboardingStep = {
|
|
|
|
title: string;
|
|
|
|
description: string;
|
|
|
|
type: "info" | "settings";
|
2024-12-15 22:32:07 +05:30
|
|
|
configurationOptions?: {
|
2024-12-15 14:25:18 +05:30
|
|
|
key: string;
|
2024-12-15 22:32:07 +05:30
|
|
|
type: "switch" | "input" | "video" | "component";
|
|
|
|
label?: string;
|
|
|
|
description?: string;
|
|
|
|
videoSrc?: string;
|
|
|
|
component?: any;
|
2024-12-15 14:25:18 +05:30
|
|
|
}[];
|
|
|
|
};
|
|
|
|
|
2024-12-15 23:23:20 +05:30
|
|
|
export function OnboardingDialog() {
|
|
|
|
const t = useTranslation();
|
|
|
|
|
|
|
|
const [currentStep, setCurrentStep] = useState(0);
|
|
|
|
const [settings, setSettings] = useState<Record<string, any>>({});
|
|
|
|
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
|
|
|
|
const onboardingSteps: OnboardingStep[] = useMemo(
|
|
|
|
() => [
|
2024-12-15 14:25:18 +05:30
|
|
|
{
|
2024-12-15 23:23:20 +05:30
|
|
|
title: t("ONBOARDING_DIALOG.STEP_1.TITLE"),
|
|
|
|
description: t("ONBOARDING_DIALOG.STEP_1.DESCRIPTION"),
|
|
|
|
type: "info",
|
2024-12-15 14:25:18 +05:30
|
|
|
},
|
|
|
|
{
|
2024-12-15 23:23:20 +05:30
|
|
|
title: t("ONBOARDING_DIALOG.STEP_2.TITLE"),
|
|
|
|
description: t("ONBOARDING_DIALOG.STEP_2.DESCRIPTION"),
|
|
|
|
type: "settings",
|
|
|
|
configurationOptions: [
|
|
|
|
{
|
|
|
|
type: "switch",
|
|
|
|
label: t("SETTINGS.AUTO_UPDATE.TITLE"),
|
|
|
|
key: "autoUpdate",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "switch",
|
|
|
|
label: t("SETTINGS.ENABLE_CONTRIBUTION.TITLE"),
|
|
|
|
description: t("SETTINGS.ENABLE_CONTRIBUTION.DESCRIPTION"),
|
|
|
|
key: "improveUpscayl",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "component",
|
|
|
|
label: t("SETTINGS.THEME.TITLE"),
|
|
|
|
component: <SelectTheme hideLabel={true} />,
|
|
|
|
key: "theme",
|
|
|
|
},
|
|
|
|
],
|
2024-12-15 22:32:07 +05:30
|
|
|
},
|
|
|
|
{
|
2024-12-15 23:23:20 +05:30
|
|
|
type: "info",
|
|
|
|
title: t("ONBOARDING_DIALOG.STEP_3.TITLE"),
|
|
|
|
description: t("ONBOARDING_DIALOG.STEP_3.DESCRIPTION"),
|
|
|
|
configurationOptions: [
|
|
|
|
{
|
|
|
|
key: "video",
|
|
|
|
type: "video",
|
2024-12-16 16:18:57 +05:30
|
|
|
videoSrc:
|
|
|
|
"https://www.youtube-nocookie.com/embed/3M77flVZlVY?autoplay=1",
|
2024-12-15 23:23:20 +05:30
|
|
|
},
|
|
|
|
],
|
2024-12-15 22:32:07 +05:30
|
|
|
},
|
|
|
|
{
|
2024-12-15 23:23:20 +05:30
|
|
|
title: t("ONBOARDING_DIALOG.STEP_4.TITLE"),
|
|
|
|
description: t("ONBOARDING_DIALOG.STEP_4.DESCRIPTION"),
|
|
|
|
type: "info",
|
2024-12-15 14:25:18 +05:30
|
|
|
},
|
|
|
|
],
|
2024-12-15 23:23:20 +05:30
|
|
|
[],
|
|
|
|
);
|
2024-12-15 22:32:07 +05:30
|
|
|
|
2024-12-15 14:25:18 +05:30
|
|
|
const currentStepData = onboardingSteps[currentStep];
|
|
|
|
const isLastStep = currentStep === onboardingSteps.length - 1;
|
|
|
|
const isFirstStep = currentStep === 0;
|
2024-12-15 22:32:07 +05:30
|
|
|
const [autoUpdate, setAutoUpdate] = useAtom(autoUpdateAtom);
|
|
|
|
const [enableContribution, setEnableContribution] = useAtom(
|
|
|
|
enableContributionAtom,
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const storedValue = localStorage.getItem("showOnboarding");
|
|
|
|
if (storedValue !== null) {
|
|
|
|
setOpen(JSON.parse(storedValue));
|
|
|
|
} else {
|
|
|
|
setOpen(true);
|
|
|
|
}
|
|
|
|
}, []);
|
2024-12-15 14:25:18 +05:30
|
|
|
|
|
|
|
const handleNext = () => {
|
|
|
|
if (isLastStep) {
|
2024-12-15 22:32:07 +05:30
|
|
|
setOpen(false);
|
|
|
|
localStorage.setItem("showOnboarding", JSON.stringify(false));
|
2024-12-15 14:25:18 +05:30
|
|
|
} else {
|
|
|
|
setCurrentStep((prev) => prev + 1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSettingChange = (key: string, value: any) => {
|
|
|
|
setSettings((prev) => ({ ...prev, [key]: value }));
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2024-12-15 22:32:07 +05:30
|
|
|
<Dialog
|
|
|
|
open={open}
|
|
|
|
onOpenChange={(e) => {
|
|
|
|
setOpen(e);
|
|
|
|
}}
|
|
|
|
>
|
2024-12-15 14:25:18 +05:30
|
|
|
<DialogContent className="flex h-[80%] w-full max-w-[80%] flex-col items-center justify-center">
|
|
|
|
<DialogHeader>
|
|
|
|
<DialogTitle className="text-center text-4xl">
|
|
|
|
{currentStepData.title}
|
|
|
|
</DialogTitle>
|
2024-12-15 22:32:07 +05:30
|
|
|
<DialogDescription className="text-center text-lg text-base-content/70">
|
2024-12-15 14:25:18 +05:30
|
|
|
{currentStepData.description}
|
|
|
|
</DialogDescription>
|
|
|
|
</DialogHeader>
|
|
|
|
|
2024-12-15 22:32:07 +05:30
|
|
|
{currentStepData.configurationOptions && (
|
|
|
|
<div
|
|
|
|
className={cn(
|
2024-12-16 16:18:57 +05:30
|
|
|
"flex h-full w-full flex-col rounded-sm bg-primary p-8",
|
2024-12-15 22:32:07 +05:30
|
|
|
currentStepData.type === "settings" && "h-auto w-auto gap-8",
|
2024-12-16 16:18:57 +05:30
|
|
|
currentStepData.configurationOptions[0].type === "video" && "p-0",
|
2024-12-15 22:32:07 +05:30
|
|
|
)}
|
|
|
|
>
|
|
|
|
{currentStepData.configurationOptions.map((option) => (
|
2024-12-15 14:25:18 +05:30
|
|
|
<div
|
2024-12-15 22:32:07 +05:30
|
|
|
key={option.key}
|
|
|
|
className="flex h-full w-full items-center justify-between gap-4"
|
2024-12-16 16:18:57 +05:30
|
|
|
data-tooltip-id="tooltip"
|
|
|
|
data-tooltip-content={
|
|
|
|
option.key === "improveUpscayl"
|
|
|
|
? t("SETTINGS.ENABLE_CONTRIBUTION.DESCRIPTION")
|
|
|
|
: null
|
|
|
|
}
|
2024-12-15 14:25:18 +05:30
|
|
|
>
|
2024-12-15 22:32:07 +05:30
|
|
|
{option.label && (
|
|
|
|
<label
|
|
|
|
htmlFor={option.key}
|
2024-12-15 23:23:20 +05:30
|
|
|
className="text-nowrap text-left text-sm uppercase text-primary-content"
|
2024-12-15 22:32:07 +05:30
|
|
|
>
|
|
|
|
{option.label}
|
|
|
|
</label>
|
|
|
|
)}
|
|
|
|
{option.type === "switch" && (
|
2024-12-15 14:25:18 +05:30
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
className="toggle"
|
2024-12-15 22:32:07 +05:30
|
|
|
id={option.key}
|
|
|
|
checked={
|
|
|
|
option.key === "autoUpdate"
|
|
|
|
? autoUpdate
|
|
|
|
: option.key === "improveUpscayl"
|
|
|
|
? enableContribution
|
|
|
|
: false
|
2024-12-15 14:25:18 +05:30
|
|
|
}
|
2024-12-15 22:32:07 +05:30
|
|
|
onChange={(e) => {
|
|
|
|
if (option.key === "autoUpdate") {
|
|
|
|
setAutoUpdate(e.target.checked);
|
|
|
|
} else if (option.key === "improveUpscayl") {
|
|
|
|
setEnableContribution(e.target.checked);
|
|
|
|
}
|
|
|
|
}}
|
2024-12-15 14:25:18 +05:30
|
|
|
/>
|
|
|
|
)}
|
2024-12-15 22:32:07 +05:30
|
|
|
{option.type === "input" && (
|
2024-12-15 14:25:18 +05:30
|
|
|
<input
|
|
|
|
className="input input-bordered"
|
2024-12-15 22:32:07 +05:30
|
|
|
id={option.key}
|
|
|
|
value={settings[option.key] || ""}
|
2024-12-15 14:25:18 +05:30
|
|
|
onChange={(e) =>
|
2024-12-15 22:32:07 +05:30
|
|
|
handleSettingChange(option.key, e.target.value)
|
2024-12-15 14:25:18 +05:30
|
|
|
}
|
|
|
|
/>
|
|
|
|
)}
|
2024-12-15 22:32:07 +05:30
|
|
|
{option.type === "video" && (
|
|
|
|
<iframe
|
2024-12-16 16:18:57 +05:30
|
|
|
className="h-full w-full rounded-sm"
|
2024-12-15 22:32:07 +05:30
|
|
|
src={option.videoSrc}
|
|
|
|
title="YouTube video player"
|
|
|
|
frameBorder="0"
|
|
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
|
|
referrerPolicy="strict-origin-when-cross-origin"
|
|
|
|
allowFullScreen
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{option.type === "component" && option.component}
|
2024-12-15 14:25:18 +05:30
|
|
|
</div>
|
|
|
|
))}
|
2024-12-16 16:18:57 +05:30
|
|
|
{currentStepData.type === "settings" && (
|
|
|
|
<p className="text-sm text-base-content/70">
|
|
|
|
{t("ONBOARDING_DIALOG.SETTINGS_NOTE")}
|
|
|
|
</p>
|
|
|
|
)}
|
2024-12-15 14:25:18 +05:30
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
|
2024-12-15 22:32:07 +05:30
|
|
|
<DialogFooter className="gap-2 md:gap-0">
|
|
|
|
<button onClick={handleNext} className="btn btn-secondary w-40">
|
2024-12-15 23:23:20 +05:30
|
|
|
{isLastStep
|
|
|
|
? t("ONBOARDING_DIALOG.GET_STARTED_BUTTON_TITLE")
|
|
|
|
: t("ONBOARDING_DIALOG.NEXT_BUTTON_TITLE")}
|
2024-12-15 14:25:18 +05:30
|
|
|
</button>
|
|
|
|
{!isFirstStep && (
|
|
|
|
<button
|
|
|
|
onClick={() => setCurrentStep((prev) => prev - 1)}
|
2024-12-15 22:32:07 +05:30
|
|
|
className="btn btn-primary w-40"
|
2024-12-15 14:25:18 +05:30
|
|
|
>
|
2024-12-15 23:23:20 +05:30
|
|
|
{t("ONBOARDING_DIALOG.BACK_BUTTON_TITLE")}
|
2024-12-15 14:25:18 +05:30
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</DialogFooter>
|
|
|
|
</DialogContent>
|
|
|
|
</Dialog>
|
|
|
|
);
|
|
|
|
}
|