feat: implement WelcomeModal component

master
Katja Lutz 2 years ago
parent d5eff6095e
commit 0c0ef7fe99

@ -0,0 +1,325 @@
import {
Component,
createEffect,
createMemo,
onCleanup,
onMount,
useContext,
} from "solid-js";
import LufraiLogo from "~icons/custom/lufrai-logo";
import AppIcon from "~icons/custom/icon";
import ExternalLinkIcon from "~icons/carbon/launch";
import LaunchIcon from "~icons/carbon/edit";
import Modal, { ModalCloseButton } from "./Modal";
import { LocalStoreContext } from "~/stores";
import createAccordion from "./Accordion";
import typer from "typer-js";
import "typer-js/dist/typer.min.css";
import { shuffle } from "~/util";
const WelcomeModal: Component = (props) => {
const [localState, setLocalState, localStateMounted] =
useContext(LocalStoreContext)!;
const [AcordionItem] = createAccordion();
let subtitleEl: HTMLSpanElement = undefined!;
const isOpen = createMemo(() => {
return localStateMounted() && localState.showWelcome;
});
onMount(function () {
let adjectives = [
"schweizerischen",
"anständigen",
"umfassenden",
"erfrischenden",
"erfreulichen",
"sauberen",
"übersichtlichen",
];
let nouns = ["Rechnung", "Auftragsbestätigung", "Offerte"];
let combinations: [string, string][] = [];
for (const adjective of adjectives) {
for (const noun of nouns) {
combinations.push([adjective, noun]);
}
}
const firstCombination = combinations.splice(0, 1)[0];
combinations = shuffle(combinations);
combinations.unshift(firstCombination!);
let typerInstance = typer(subtitleEl, { min: 60, max: 160 });
let lastAdjective = "";
let lastNoun = "";
for (const [adjective, noun] of combinations) {
const first = lastAdjective === "";
if (lastAdjective === adjective) {
typerInstance.back(lastNoun.length, 80).continue(noun);
} else {
const method = first ? "line" : "continue";
typerInstance
.back("all", 65)
[method](
`${adjective} ${noun}`,
first ? { min: 60, max: 70 } : undefined
);
}
typerInstance.pause(first ? 4181 : 6765);
lastNoun = noun;
lastAdjective = adjective;
}
typerInstance.back("all", 50).repeat(Infinity);
let halted = false;
createEffect(function () {
if (!isOpen()) {
halted = typerInstance.halt() === undefined;
} else {
try {
// typer-js has some weird logic how it handles halt / resume. Essentially if halt wasn't executed before of resume, resume breaks completely
halted && typerInstance.resume();
} catch (err) {
console.log(err);
}
halted = false;
}
});
onCleanup(function () {
typerInstance.kill();
});
});
return (
<Modal open={isOpen()}>
<ModalCloseButton onClick={() => setLocalState("showWelcome", false)} />
<div class="max-h-[50vh] overflow-y-auto">
<div class="h-[50vh] flex items-center justify-center">
<div>
<div class="flex flex-col items-center">
<div class="mb-3 text-8xl flex items-end justify-between w-[370px] font-bold tracking-tighter leading-none text-swiss-red fill-current">
<AppIcon height="0.9em" />
<div>Räppli</div>
</div>
<div class="flex flex-col items-stretch">
<div class="flex justify-center">
<div class="text-gray-800 tracking-widest mb-4 flex gap-1">
Der reibungslose Weg zur{" "}
<span class="ignore-white-space" ref={subtitleEl}></span>
</div>
</div>
</div>
<div class="flex justify-end w-[410px]">
<a
href="https://lufrai.org"
target="_blank"
rel="noopener"
class="text-lufrai-primary-darker hover:text-lufrai-primary transition-colors fill-current text-base flex items-center leading-tight gap-2 tracking-tighter font-bold border-b border-lufrai-primary-light border-opacity-20 pb-1"
>
<span>made</span>
<span>by</span>
<LufraiLogo class="w-auto h-[1.5em]" />
</a>
</div>
</div>
<div class="mt-28 flex text-center gap-7 items-center justify-center">
<a class="link link-secondary" href="#welcome-quickstart">
Einleitung
</a>
<a class="link link-secondary" href="#welcome-why-free">
Wieso ist Räppli <br />
<strong>komplett kostenlos</strong>?
</a>
<a class="link link-secondary" href="#welcome-lufrai">
Was ist Lufrai?
</a>
<a class="link link-secondary" href="#welcome-support">
Das Projekt
<br />
unterstützen
</a>
<a
class="link link-secondary"
title="Häufig gestellte Fragen"
href="#welcome-faq"
>
FAQ
</a>
<a
class="link link-secondary flex items-center gap-2"
target="_blank"
rel="noopener"
href="https://git.lufrai.com/rappli/rappli"
>
Git-Repository
<ExternalLinkIcon />
</a>
</div>
</div>
</div>
<div class="mt-20 prose max-w-none">
<section>
<h1 id="welcome-quickstart">Einleitung</h1>
<p>
Sit aute excepteur labore eu non eiusmod nulla irure irure
officia. Veniam pariatur dolore fugiat mollit cillum. Et id
occaecat occaecat non duis. Veniam excepteur do labore sit nulla
veniam non ad nisi qui proident adipisicing esse adipisicing ea.
Officia do esse magna dolore irure voluptate pariatur consequat
esse voluptate. Incididunt incididunt mollit nostrud laborum
cupidatat proident tempor reprehenderit officia exercitation
labore. Commodo minim fugiat mollit commodo. Sit anim est aute.
Ullamco non deserunt deserunt aliquip labore sunt esse Lorem aute
in nisi mollit irure deserunt labore. Lorem veniam in consequat
ipsum consequat sint consectetur ex anim magna.
</p>
</section>
<section class="mt-16">
<h1 id="welcome-why-free">
Wieso ist <span class="text-swiss-red">Räppli</span> komplett{" "}
<span class="text-swiss-red">kostenlos</span>?
</h1>
<p>
Consectetur id magna labore commodo exercitation laboris est
laboris consectetur irure minim. Officia anim tempor adipisicing
irure labore tempor reprehenderit culpa consequat ea esse
exercitation. Consectetur labore velit nulla excepteur eiusmod sit
fugiat do proident. Ex non consectetur mollit dolor dolore Lorem
ut et incididunt pariatur sunt deserunt tempor magna ullamco.
</p>
</section>
<section class="mt-16">
<h1 id="welcome-lufrai">
Was ist <span class="text-lufrai-primary">Lufrai</span>?
</h1>
<p>
Quis occaecat pariatur laborum do ad esse. Mollit excepteur duis
nulla proident nostrud tempor ad ullamco. Amet id magna aute esse
tempor incididunt pariatur veniam ipsum qui. Sunt laboris in
laborum reprehenderit qui sint consectetur nostrud excepteur
proident proident laboris qui dolor ea. Reprehenderit tempor elit
consequat dolore quis ad voluptate consequat. Eiusmod ad quis
dolore dolore ea ipsum commodo eu aliquip veniam. Consequat
pariatur est do sint nisi duis enim tempor occaecat elit non.
</p>
</section>
<section class="mt-16">
<h1 id="welcome-support">Das Projekt unterstützen</h1>
<p>
Irure laboris quis consequat enim tempor dolor. Esse velit
occaecat dolore aute cillum pariatur reprehenderit irure duis eu
nulla pariatur fugiat consectetur ipsum. Commodo ad aliquip nulla
non incididunt. Officia veniam cillum cillum. Velit ex aliquip
mollit deserunt nostrud id amet voluptate ea duis cupidatat
officia culpa consequat enim. Voluptate anim fugiat anim et elit
aute cupidatat. Duis aliquip laboris adipisicing dolore elit
voluptate proident occaecat excepteur culpa exercitation velit.
Veniam esse quis voluptate aliquip culpa. Aute cupidatat sunt amet
ad fugiat id elit. Officia proident ea deserunt quis anim elit
cupidatat pariatur. Aliqua dolore ad eiusmod qui eu ea enim qui
enim incididunt aute irure tempor fugiat sunt. Consequat magna
culpa Lorem nostrud cillum eu cillum adipisicing eu aute duis
excepteur. In anim mollit amet elit ex.
</p>
</section>
<section class="mt-16">
<h1 id="welcome-faq">Häufig gestellte Fragen</h1>
<div class="text-black">
<AcordionItem
item={0}
label={"Wo werden meine Daten gespeichert?"}
>
test
</AcordionItem>
<AcordionItem label="Ich habe vergessen zu speichern!?">
test
</AcordionItem>
<AcordionItem
label={
<div class="text-center">
Ich habe einen Anpassungswunsch!
<br />
Kann die App bitte gratis angepasst werden?
</div>
}
>
test
</AcordionItem>
<AcordionItem label={"Welche Geräte werden unterstützt?"}>
test
</AcordionItem>
<AcordionItem label={"Wer hat's erfunden?"}>test</AcordionItem>
<AcordionItem label={'Was heisst "Open Source"?'}>
test
</AcordionItem>
<AcordionItem
label={
<div class="text-center">
Können Fliesstexte formatiert werden?
<br />
Was ist <strong>Markdown</strong>?
</div>
}
>
test
</AcordionItem>
</div>
</section>
</div>
</div>
<div class="mt-14 relative flex justify-center gap-10">
<div
class="form-control flex-row items-center gap-2"
title="Unterstütze Lufrai mit einem Wasserzeichen im Dokument"
>
<input
checked={localState.showLufraiWatermark}
class="checkbox checkbox-lg checkbox-accent"
type="checkbox"
onClick={(evt) =>
setLocalState("showLufraiWatermark", evt.currentTarget.checked)
}
/>
<button
onClick={() =>
setLocalState(
"showLufraiWatermark",
!localState.showLufraiWatermark
)
}
class="btn btn-sm btn-accent text-gap-2 shadow-2xl shadow-lufrai-primary-darker"
>
Lufrai Wasserzeichen
</button>
</div>
<button
onClick={() => setLocalState("showWelcome", false)}
class="btn btn-xl btn-primary gap-2 shadow-2xl shadow-indigo-900"
>
<LaunchIcon />
Loslegen
</button>
</div>
</Modal>
);
};
export default WelcomeModal;
Loading…
Cancel
Save