You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
941 lines
37 KiB
TypeScript
941 lines
37 KiB
TypeScript
import {
|
|
Component,
|
|
createEffect,
|
|
createMemo,
|
|
FlowComponent,
|
|
onCleanup,
|
|
onMount,
|
|
JSX,
|
|
useContext,
|
|
splitProps,
|
|
} from "solid-js";
|
|
import LufraiLogo from "~icons/custom/lufrai-logo";
|
|
import AppIcon from "~icons/custom/icon";
|
|
import ExternalLinkIcon from "~icons/carbon/launch";
|
|
import WarningIcon from "~icons/carbon/warning-alt-filled";
|
|
import LaunchIcon from "~icons/carbon/edit";
|
|
import DonationIcon from "~icons/carbon/favorite-filled";
|
|
import WatermarkIcon from "~icons/carbon/bullhorn";
|
|
import FreedomIcon from "~icons/noto/butterfly";
|
|
import FreeIcon from "~icons/noto/seedling";
|
|
import PrivacyIcon from "~icons/noto/princess";
|
|
import AgileIcon from "~icons/noto/person-bouncing-ball";
|
|
import ResultIcon from "~icons/noto/chequered-flag";
|
|
import HugIcon from "~icons/noto/hugging-face";
|
|
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 {
|
|
externalLink,
|
|
getDisplayDate,
|
|
getDomain,
|
|
getHost,
|
|
onClickFocus,
|
|
shuffle,
|
|
} from "~/util";
|
|
import { capitalize } from "froebel";
|
|
import { markdownHelpUrl } from "./Markdown";
|
|
import AgileCalculator from "./AgileCalculator";
|
|
|
|
export const description =
|
|
"Räppli ist eine freie Web App zur Erstellung von Schweizerischen Rechnungen inklusive QR-Code. Erfasse deine Rechnungspositionen und erhalte unmittelbar eine druckbare Rechnung.";
|
|
|
|
const externalLinkClass = "inline-flex items-center gap-1";
|
|
|
|
const ExternalLink: FlowComponent<
|
|
JSX.AnchorHTMLAttributes<HTMLAnchorElement>
|
|
> = (p) => {
|
|
const [props, rest] = splitProps(p, ["children"]);
|
|
return (
|
|
<a class={externalLinkClass} {...externalLink} {...rest}>
|
|
{props.children}
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
);
|
|
};
|
|
|
|
const WelcomeModal: Component = (props) => {
|
|
const [localState, setLocalState, localStateMounted] =
|
|
useContext(LocalStoreContext)!;
|
|
const [AccordionItem] = 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) {
|
|
if ((err as TypeError).message != "u.resume is not a function") {
|
|
console.dir(err);
|
|
}
|
|
}
|
|
halted = false;
|
|
}
|
|
});
|
|
|
|
onCleanup(function () {
|
|
typerInstance.kill();
|
|
});
|
|
});
|
|
|
|
const ShareonLink: Component<{ provider: string; via?: string }> = (
|
|
props
|
|
) => (
|
|
<a
|
|
class={props.provider + " shadow"}
|
|
title={capitalize(props.provider)}
|
|
data-via={props.via}
|
|
aria-label={`Share on ${capitalize(props.provider)}`}
|
|
></a>
|
|
);
|
|
|
|
// I hope Randomness will guarantee a fair sequence <3
|
|
const thankYouRahelAndFredi = shuffle([
|
|
<>
|
|
Fredi Niklaus (
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://www.remedyit.ch/"
|
|
{...externalLink}
|
|
>
|
|
RemedyIT <ExternalLinkIcon />
|
|
</a>
|
|
)
|
|
</>,
|
|
"Rahel Lutz",
|
|
]);
|
|
thankYouRahelAndFredi.splice(1, 0, " und ");
|
|
|
|
return (
|
|
<Modal open={isOpen()}>
|
|
<div class="hidden xl:block">
|
|
<ModalCloseButton onClick={() => setLocalState("showWelcome", false)} />
|
|
</div>
|
|
<div class="max-h-[60vh] overflow-y-auto px-2">
|
|
<div class="min-h-[60vh] flex items-center justify-center">
|
|
<div>
|
|
<div class="flex flex-col items-center justify-around">
|
|
<div class="mt-3 mb-3 text-6xl lg:text-8xl flex items-end lg:w-[370px] justify-between gap-2 lg:gap-0 font-bold tracking-tighter leading-none text-swiss-red fill-current">
|
|
<AppIcon class="w-auto h-[0.9em]" />
|
|
<div>Räppli</div>
|
|
</div>
|
|
<div class="flex flex-col items-stretch">
|
|
<div class="flex justify-center">
|
|
<div class="text-gray-800 text-sm lg:text-base tracking-widest mb-4 flex gap-1 flex-col items-center lg:flex-row">
|
|
Der reibungslose Weg zur{" "}
|
|
<span class="ignore-white-space" ref={subtitleEl}></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-end lg:w-[410px] max-w-full">
|
|
<a
|
|
href="https://lufrai.org"
|
|
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"
|
|
{...externalLink}
|
|
>
|
|
<span>made</span>
|
|
<span>by</span>
|
|
<LufraiLogo class="w-auto h-[1.5em]" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-28 text-base flex flex-wrap text-center gap-7 items-center justify-center">
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary"
|
|
href="#welcome-quickstart"
|
|
>
|
|
Einleitung
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary"
|
|
href="#welcome-why-free"
|
|
>
|
|
Wieso ist Räppli <br />
|
|
<strong>komplett kostenlos</strong>?
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary"
|
|
href="#welcome-lufrai"
|
|
>
|
|
Was ist Lufrai?
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary"
|
|
href="#welcome-patron"
|
|
>
|
|
Das Projekt
|
|
<br />
|
|
unterstützen
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary flex items-center gap-2"
|
|
href="#welcome-opensource"
|
|
>
|
|
Open Source
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary flex items-center gap-2"
|
|
href="#welcome-thankyou"
|
|
>
|
|
Danksagungen
|
|
</a>
|
|
<a
|
|
class="link text-secondary-focus hover:text-secondary"
|
|
title="Häufig gestellte Fragen"
|
|
href="#welcome-faq"
|
|
>
|
|
FAQ
|
|
</a>
|
|
</div>
|
|
|
|
<div class="mt-16 flex flex-wrap gap-3 items-center justify-center">
|
|
<div class="text-sm text-slate-600">Teile es auf:</div>
|
|
<div
|
|
class="shareon flex flex-wrap items-center justify-center"
|
|
data-title="Hast du schon von Räppli gehört? Es ist ein praktisches Web App, womit Schweizer QR Rechnungen inkl. Rechnungspositionen erstellt werden können und es ist komplett kostenlos! Probiere es aus unter:"
|
|
data-url={getHost()}
|
|
>
|
|
<ShareonLink provider="mastodon" />
|
|
<ShareonLink provider="telegram" />
|
|
<ShareonLink provider="reddit" />
|
|
<ShareonLink provider="odnoklassniki" />
|
|
<ShareonLink provider="pinterest" />
|
|
<ShareonLink provider="pocket" />
|
|
<ShareonLink provider="viber" />
|
|
<ShareonLink provider="vkontakte" />
|
|
<ShareonLink provider="linkedin" />
|
|
<ShareonLink provider="twitter" via="katy_wings" />
|
|
<ShareonLink provider="facebook" />
|
|
<ShareonLink provider="whatsapp" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-20 prose text-opacity-100">
|
|
<section>
|
|
<h2 id="welcome-quickstart">Einleitung</h2>
|
|
<p class="text-xl font-light lead">{description}</p>
|
|
<p>
|
|
Du möchtest dich <strong>selbstständig machen</strong>, gründest
|
|
gerade ein <strong>Startup</strong> oder einen{" "}
|
|
<strong>Verein</strong> und musst in der Lage sein{" "}
|
|
<strong>Rechnungen, Offerten und Auftragsbestätigungen</strong> zu
|
|
verschicken? Du möchtest dabei <strong>unabhängig</strong>{" "}
|
|
bleiben? Dann bist du hier genau richtig!
|
|
</p>
|
|
<p>Vorteile von Räppli:</p>
|
|
<ul>
|
|
<li>
|
|
<ResultIcon class="inline-block scale-150 mr-2" /> Die
|
|
praktische Vorschau zeigt dir sofort das Endergebnis.
|
|
</li>
|
|
<li>
|
|
<PrivacyIcon class="inline-block scale-150 mr-2" />
|
|
Deine Daten bleiben{" "}
|
|
<a onClick={onClickFocus} href="#welcome-privacy">
|
|
bei dir
|
|
</a>
|
|
.
|
|
</li>
|
|
<li>
|
|
<FreeIcon class="inline-block scale-150 mr-2" /> Räppli ist und
|
|
bleibt <a href="#welcome-why-free">komplett kostenlos</a>!
|
|
</li>
|
|
<li>
|
|
<FreedomIcon class="inline-block scale-150 mr-2" /> Der
|
|
Quellcode ist{" "}
|
|
<a href="#welcome-opensource">vollumfänglich öffentlich</a>.
|
|
Räppli kann selbst gehostet werden!
|
|
</li>
|
|
<li>
|
|
<AgileIcon class="inline-block scale-150 mr-2" /> Du arbeitest{" "}
|
|
<a onClick={onClickFocus} href="#welcome-agile">
|
|
agil
|
|
</a>
|
|
? Räppli kann dir dabei helfen einen Preis zu kalkulieren!
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-why-free">
|
|
Wieso ist <span class="text-swiss-red">Räppli</span> komplett{" "}
|
|
<span class="text-swiss-red">kostenlos</span>?
|
|
</h2>
|
|
<p class="text-xl font-light lead">
|
|
Weil moderne Rechnungsstellung für alle Menschen möglich sein
|
|
sollte!
|
|
</p>
|
|
<p>
|
|
Jeder Selbstständige kommt wohl irgendwann an den Punkt, dass er
|
|
eine Rechnung schreiben muss. Doch eine moderne Rechnung zu
|
|
schreiben, die heutige Erwartungen erfüllt, ist gar nicht so
|
|
einfach und braucht viel Zeit. So werden viele Selbstständige zum
|
|
Einsatz von komplexer und oftmals teurer "ERP"-Software oder zu
|
|
Outsourcing gedrängt. Menschen die sich mit wenig Startkapital
|
|
selbstständig machen wollen, stehen vor einer schwierigen Wahl.
|
|
</p>
|
|
<p>
|
|
Eines der wesentlichen Ziele von{" "}
|
|
<a href="#welcome-lufrai">Lufrai</a> ist, Menschen dabei zu
|
|
unterstützen aus eigener Kraft unabhängig zu werden und ihrem
|
|
eigenen Lebenssinn zu folgen. <i>Befreie deine Stimme!</i>
|
|
</p>
|
|
<p>
|
|
Räppli soll ein Beweis dafür darstellen, dass Selbstlosigkeit auch
|
|
ohne teure, zentralisierte, staatliche Lösungen möglich ist. Der
|
|
gesamte Quellcode von Räppli steht offen verfügbar.{" "}
|
|
<a href="#welcome-opensource">Erfahre mehr</a>
|
|
</p>
|
|
<p>
|
|
Zu guter Letzt ist Räppli auch eine Referenzarbeit. Sie soll
|
|
zeigen was ich (Katja) als Web-Entwicklerin drauf habe. Denn im
|
|
mündlichen Gespräch verkaufe ich meine Fähigkeiten leider wie eine
|
|
absolute Niete und wirke mit einer Grösse von 1.9 Metern etwas
|
|
abschreckend. Verkauf ist nicht meine Stärke.
|
|
</p>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-lufrai">
|
|
Was ist <span class="text-lufrai-primary">Lufrai</span>?
|
|
</h2>
|
|
<p>
|
|
Lufrai ist die Einzelfirma von{" "}
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://lufrai.org/katjalutz"
|
|
{...externalLink}
|
|
>
|
|
Katja Lutz <ExternalLinkIcon />
|
|
</a>
|
|
. Sie setzt sich als Web-Entwicklerin, Künstlerin und Aktivistin
|
|
für eine unabhängige, freie Schweiz ein und unterstützt ihre
|
|
souveränen Mitmenschen, das Steuer selbst in die Hand zu nehmen.
|
|
<a
|
|
class="btn btn-sm inline-flex ml-3 items-center gap-1"
|
|
href="https://lufrai.org"
|
|
{...externalLink}
|
|
>
|
|
Erfahre mehr <ExternalLinkIcon />
|
|
</a>
|
|
</p>
|
|
<p>Grundsätze:</p>
|
|
<ol class="prose-sm">
|
|
<li>Zuoberst steht der Mensch.</li>
|
|
<li>
|
|
Selbstverantwortlich zu leben heisst, zu geben und anzunehmen.
|
|
<br />
|
|
Miteinander zu leben heisst, zu vergeben.
|
|
</li>
|
|
<li>
|
|
Erkenntnis kommt von Innen und Altruismus kann nicht erzwungen
|
|
werden.
|
|
</li>
|
|
<li>
|
|
Nötigung drängt den Horizont zusammen, Aufklärung erweitert ihn.
|
|
</li>
|
|
<li>
|
|
Gleichheit setzt voraus, sich auf Augenhöhe zu begegnen und
|
|
Privatsphäre zu respektieren.
|
|
</li>
|
|
<li>
|
|
Achtsam ist, wer global denkt, aber lokal handelt. <br />
|
|
Gute Entscheidungen trifft, wer die Konsequenzen begreift.
|
|
</li>
|
|
<li>
|
|
Der Technik die Entscheidung zu überlassen heisst, selbst zur
|
|
Maschine zu werden.
|
|
</li>
|
|
<li>
|
|
Schönheit ist nicht selbstverständlich, sie entspringt aus der
|
|
Bereitschaft zur Veränderung.
|
|
</li>
|
|
<li>
|
|
Anführer zeichnen sich nicht durch ihre Lautstärke und Forderung
|
|
aus, sondern durch Selbstlosigkeit und Transparenz.
|
|
</li>
|
|
<li>Zensur betreibt, wer etwas verbergen will.</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-patron">Das Projekt unterstützen</h2>
|
|
<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>
|
|
<h3>Spende</h3>
|
|
<h3>Mitwirkung</h3>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-opensource">Open Source</h2>
|
|
<p>
|
|
Du hast richtig gehört, Räppli ist Open Source! Jeder kann Räppli
|
|
kopieren, verteilen und erweitern. Du brauchst also keine Angst zu
|
|
haben, dass du irgendwann keine Rechnungen mehr schreiben darfst.
|
|
Lizenziert ist Räppli mit{" "}
|
|
<ExternalLink href="https://git.lufrai.com/rappli/rappli/src/branch/master/LICENSE">
|
|
MIT
|
|
</ExternalLink>
|
|
.
|
|
<a
|
|
class="btn btn-sm inline-flex ml-3 items-center gap-1"
|
|
href="https://git.lufrai.com/rappli/rappli"
|
|
{...externalLink}
|
|
>
|
|
Git-Repository
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
<br />
|
|
<strong>
|
|
Falls du dich dort zur Mitwirkung registrieren möchtest: Bitte
|
|
schreibe mir nach deiner Registrierung ein kurzes Mail mit
|
|
deiner Motivation an "contact(at)lufrai.org", damit ich dich
|
|
freischalten kann.
|
|
</strong>
|
|
</p>
|
|
<p>
|
|
Eingesetzte Technologien (<small>Nur um einige zu nennen</small>):
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://www.solidjs.com/"
|
|
{...externalLink}
|
|
>
|
|
Solid
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://tailwindcss.com/"
|
|
{...externalLink}
|
|
>
|
|
Tailwind CSS
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://daisyui.com/"
|
|
{...externalLink}
|
|
>
|
|
daisyUI
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://sortablejs.github.io/Sortable/"
|
|
{...externalLink}
|
|
>
|
|
Sortable
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://remark.js.org/"
|
|
{...externalLink}
|
|
>
|
|
remark
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-thankyou">Danksagungen</h2>
|
|
<p>
|
|
An dieser Stelle möchte ich (Katja) mich bei der Community von{" "}
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://www.solidjs.com/"
|
|
{...externalLink}
|
|
>
|
|
Solid <ExternalLinkIcon />
|
|
</a>{" "}
|
|
bedanken, nicht nur für ihr verblüffend effektives Open Source
|
|
Web-Framework, sondern auch für ihre Offenheit, Anregungen und
|
|
cleveren Tipps!
|
|
</p>
|
|
<p>
|
|
Ausserdem möchte ich mich insbesondere bei {thankYouRahelAndFredi}{" "}
|
|
herzlichst bedanken, welche mir stets bei der Umsetzung meiner
|
|
kurligen Projekte unterstützend zur Seite standen und mich immer
|
|
inspirierten, einen Schritt weiterzugehen!
|
|
</p>
|
|
<p>
|
|
Mein herzlicher Dank gilt zudem auch{" "}
|
|
<ExternalLink href="https://www.kohei.dev/en-us">
|
|
Kohei Asai
|
|
</ExternalLink>
|
|
, welcher mir sehr grosszügig seine Rechte am Paketnamen "rappli"
|
|
auf{" "}
|
|
<ExternalLink href="https://npmjs.com">npmjs.com</ExternalLink>{" "}
|
|
übertragen hat.
|
|
</p>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h2 id="welcome-faq">Häufig gestellte Fragen</h2>
|
|
<div class="text-black">
|
|
<AccordionItem
|
|
id="welcome-privacy"
|
|
label={"1. Wo werden welche Daten gespeichert?"}
|
|
alignCenter={false}
|
|
>
|
|
<ul>
|
|
<li>
|
|
Deine eingegebenen Daten werden an keine Server übermittelt.
|
|
</li>
|
|
<li>
|
|
Einige deiner Daten, wie z.B. Bankverbindung, Logo und
|
|
Zahlungsbedingungen verbleiben im{" "}
|
|
<span
|
|
class="text-title-border"
|
|
title="Der sogennante localStorage"
|
|
>
|
|
Speicher
|
|
</span>{" "}
|
|
von deinem Browser. So musst du sie nicht jedes Mal neu
|
|
erfassen, wenn du eine Rechnung schreiben willst.
|
|
</li>
|
|
<li>
|
|
Damit das Internet und somit auch Räppli überhaupt
|
|
funktionieren, müssen jedoch unweigerlich einige Daten
|
|
übertragen werden, wie z.B. deine IP-Adresse. Erfahre{" "}
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://t3n.de/news/tcp-ip-internet-grundlagen-755667/"
|
|
{...externalLink}
|
|
>
|
|
hier
|
|
<ExternalLinkIcon />
|
|
</a>{" "}
|
|
wie das Internet funktioniert.
|
|
</li>
|
|
</ul>
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label="2. Ich habe vergessen zu speichern, was nun?!"
|
|
alignCenter={false}
|
|
>
|
|
Deine Daten werden auf keinem Server gespeichert. Lerne aus dem
|
|
Malheur und speichere ab sofort regelmässig{" "}
|
|
<HugIcon class="inline" />!
|
|
</AccordionItem>
|
|
|
|
<AccordionItem label="3. Werden meine Nutzungsdaten zu Marketingzwecken gesammelt?">
|
|
<strong>Nein</strong>, vorausgesetzt du verwendest das
|
|
offizielle Räppli über rappli.ch und keine modizifierte Version.
|
|
Lufrai legt Wert auf deine Privatsphäre. Es werden keine
|
|
Nutzungsdaten an Google, Facebook oder ähnliche Riesen
|
|
übermittelt.
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label={
|
|
<>
|
|
4. Ich habe einen Anpassungswunsch!
|
|
<br />
|
|
Kann die App bitte gratis angepasst werden?
|
|
</>
|
|
}
|
|
alignCenter={false}
|
|
>
|
|
Räppli ist <a href="#welcome-opensource">Open Source</a> und
|
|
wird grundsätzlich von <a href="#welcome-lufrai">Lufrai</a>{" "}
|
|
weiterentwickelt. Für eine optimale Weiterentwicklung ist dein
|
|
Feedback sehr wichtig und ich (Katja) bin für dein Feedback und
|
|
deine Ideen dankbar! Jedoch besteht keine Garantie dafür, dass
|
|
jedes Feedback beantwortet / umgesetzt werden kann, die
|
|
Entwicklung ist aufwändig und kein Wunschkonzert. Kontaktiere
|
|
Lufrai auf{" "}
|
|
<a
|
|
href="https://lufrai.org/impressum/"
|
|
class={externalLinkClass}
|
|
{...externalLink}
|
|
>
|
|
Kontakt <ExternalLinkIcon />
|
|
</a>{" "}
|
|
oder erstelle ein Issue auf dem{" "}
|
|
<a href="#welcome-opensource">Git-Repository</a>.
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
id="welcome-agile"
|
|
label={
|
|
<div>
|
|
5. Wie funktionieren <strong>Agile Positionen</strong>?
|
|
</div>
|
|
}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0 text-lg font-light lead">
|
|
Agile Positionen können dir dabei helfen, Arbeitsaufwand
|
|
(Zeit) zu schätzen.
|
|
</p>
|
|
<p>
|
|
Der Preis von agilen Positionen wird aus Story Points, einem
|
|
Umrechnungssatz "Stunden pro Story Point", dem Risiko Faktor
|
|
und dem Stundensatz ("Einzelpreis") berechnet.
|
|
</p>
|
|
<h3>Was sind Story Points?</h3>
|
|
<p>
|
|
Story Points sind relative Punktzahlen. Weise all deinen
|
|
Positionen Story Points zu, die im Verhältnis zueinander
|
|
stimmen. Vergleiche dazu deine Positionen und überlege dir,
|
|
welche davon schwieriger sind und welche einfacher. Wie viel
|
|
schwieriger ist eine Position (Arbeitsaufwand) im Vergleich zu
|
|
einer anderen?
|
|
</p>
|
|
<p>
|
|
Nachdem du die Story Points zugewiesen hast, kannst du dir
|
|
überlegen, wie viel Stunden ein einzelner Story Point wert
|
|
ist, trage diesen in den "Dokument"-Einstellungen unter
|
|
"Stunden pro Story Point" ein.
|
|
</p>
|
|
<a
|
|
href="https://www.agile-academy.com/de/product-owner/was-sind-story-points/"
|
|
class={externalLinkClass}
|
|
{...externalLink}
|
|
>
|
|
Erfahre mehr über Story Points
|
|
<ExternalLinkIcon />
|
|
</a>
|
|
<h3>Was ist der Risiko Faktor?</h3>
|
|
<p>
|
|
Aufwandschätzungen sind eine riskante Angelegenheit. Räppli
|
|
erlaubt dir deshalb für den geschätzten, optimalen Fall "Story
|
|
Points Minimum" und für den schlimmsten Fall "Story Points
|
|
Maximum" anzugeben.
|
|
<br />
|
|
<strong>
|
|
Der Risiko Faktor wird in den "Dokument"-Einstellungen
|
|
eingegeben und er entscheidet über die Gewichtung der
|
|
minimalen und maximalen Story Points:
|
|
</strong>
|
|
</p>
|
|
<ul class="mb-8">
|
|
<li>
|
|
Risiko Faktor von <span class="underline">0%</span>: Es
|
|
existiert kein Risiko, <strong>nur die minimalen</strong>{" "}
|
|
Story Points werden beachtet!
|
|
</li>
|
|
<li>
|
|
Risiko Faktor von <span class="underline">70%</span>:{" "}
|
|
<strong>30% von den Minimalen</strong>, und{" "}
|
|
<strong>70% von den maximalen</strong> Story Points werden
|
|
beachtet.
|
|
</li>
|
|
<li>
|
|
Risiko Faktor von <span class="underline">100%</span>: Der
|
|
Worst-Case ist alternativlos,{" "}
|
|
<strong>nur die maximalen</strong> Story Points werden
|
|
beachtet!
|
|
</li>
|
|
</ul>
|
|
|
|
<AgileCalculator />
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label={"6. Welche Geräte werden unterstützt?"}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0">
|
|
Räppli wurde für Geräte mit grösseren Bildschirmen wie z.B.
|
|
Laptops und Computer programmiert. Die besten Druckergebnisse
|
|
werden erfahrungsgemäss mit dem Browser "Mozilla Firefox"
|
|
erreicht, jedoch sind auch "Google Chrome" basierte Browser
|
|
geeignet. Verwende einen aktuellen Browser!
|
|
</p>
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label={
|
|
<div>
|
|
7. Können Fliesstexte formatiert werden?
|
|
<br />
|
|
Was ist <strong>Markdown</strong>?
|
|
</div>
|
|
}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0 mb-1">
|
|
Du kannst deinen Text formatieren, indem du ihn mit ganz
|
|
bestimmten Zeichen versiehst! Welche Zeichen das sind, wird
|
|
durch den "Markdown"-Standard definiert.
|
|
</p>
|
|
<p class="mt-1">
|
|
Erfahre{" "}
|
|
<a
|
|
href={markdownHelpUrl}
|
|
class={externalLinkClass}
|
|
{...externalLink}
|
|
>
|
|
hier <ExternalLinkIcon />
|
|
</a>{" "}
|
|
wie Markdown im Detail funktioniert!
|
|
</p>
|
|
|
|
<strong>Kurzbeispiel:</strong>
|
|
<div class="prose-sm">
|
|
<div class="grid grid-cols-2">
|
|
<p>Dein Text:</p>
|
|
<pre>
|
|
{["- *Pizza*", "- **Gemüse**", "- ***Salat***"].join(
|
|
"\n"
|
|
)}
|
|
</pre>
|
|
<p>Ausgabe:</p>
|
|
<div class="border border-slate-200">
|
|
<ul>
|
|
<li>
|
|
<i>Pizza</i>
|
|
</li>
|
|
<li>
|
|
<strong>Gemüse</strong>
|
|
</li>
|
|
<li>
|
|
<i>
|
|
<strong>Salat</strong>
|
|
</i>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
id="welcome-local-installation"
|
|
label={<div>8. Kann Räppli lokal installiert werden?</div>}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0">
|
|
Räppli kann lokal installiert werden, jedoch ist es für den
|
|
Betrieb auf Servern optimiert. Das heisst: auch wenn du Räppli
|
|
installiert hast, musst du deinen Webbrowser nutzen, um Räppli
|
|
zu öffnen.
|
|
</p>
|
|
<p class="bg-slate-500/10 flex p-3 items-center gap-3 rounded">
|
|
<WarningIcon class="w-auto h-6 inline mr-1" />{" "}
|
|
<strong>
|
|
Für die Installation sind grundlegende Kenntnisse im Umgang
|
|
mit der Kommandozeile empfohlen!
|
|
</strong>
|
|
</p>
|
|
<h3>Voraussetzungen:</h3>
|
|
<ul>
|
|
<li>
|
|
Installiere{" "}
|
|
<a
|
|
class={externalLinkClass}
|
|
href="https://nodejs.org/en/"
|
|
{...externalLink}
|
|
>
|
|
nodejs {">"}= 18 <ExternalLinkIcon />
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<h3>Installation Räppli</h3>
|
|
<p>Führe folgenden Befehl aus:</p>
|
|
<pre>npm install -g rappli</pre>
|
|
<h3>Räppli starten</h3>
|
|
<p>Führe folgenden Befehl aus, um Räppli zu starten</p>
|
|
<pre>rappli</pre>
|
|
<p>
|
|
Sobald die Meldung "Listening on port 3000" erscheint, kannst
|
|
du dein lokales Räppli auf deinem Browser über{" "}
|
|
<a href="http://localhost:3000" {...externalLink}>
|
|
http://localhost:3000
|
|
</a>{" "}
|
|
erreichen.
|
|
</p>
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label={
|
|
<div>
|
|
9. Wie präzise wurden die SIX QR-Rechnung Vorgaben
|
|
umgesetzt?
|
|
</div>
|
|
}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0">
|
|
Es handelt sich bewusst nicht um eine Pixel-genaue Umsetzung
|
|
der Vorgaben von SIX. Das Design der QR-Rechnung orientiert
|
|
sich am Grundsatz des pragmatischen Perfektionismus. Das
|
|
heisst: es wurden die Möglichkeiten des Design Frameworks
|
|
"Tailwind CSS" genutzt, um die Vorgaben von SIX möglichst
|
|
genau umzusetzen, aber da dabei nicht die unerschöpflichen
|
|
Mittel der Schweizer Regierung zur Verfügung standen, wurde
|
|
das Rad nicht komplett neu erfunden.
|
|
</p>
|
|
</AccordionItem>
|
|
|
|
<AccordionItem
|
|
label={<div>10. Haftungsausschluss</div>}
|
|
alignCenter={false}
|
|
>
|
|
<p class="!mt-0">
|
|
Räppli ({getDomain()}) verwendest du{" "}
|
|
<strong>eigenverantwortlich</strong>. "Lufrai - Katja Lutz"
|
|
(Einzelfirma) und "Katja Lutz" (Mensch) übernehmen keine
|
|
Haftung.
|
|
</p>
|
|
<p>
|
|
Es besteht kein Anspruch auf die Verfügbarkeit von{" "}
|
|
{getDomain()}. Falls du 100% sicher sein willst, dass du
|
|
Räppli auch in aussergewöhnlichen Zeiten verwenden kannst,
|
|
besorge dir den Quellcode jetzt und{" "}
|
|
<a href="#welcome-local-installation" onClick={onClickFocus}>
|
|
installiere Räppli lokal
|
|
</a>
|
|
.
|
|
</p>
|
|
</AccordionItem>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
<div class="mt-14 relative flex justify-center items-center gap-10">
|
|
<a
|
|
href="#welcome-patron"
|
|
class="hidden xl:flex btn btn-sm btn-secondary bg-purple-600 border-purple-600 gap-2 transition-all shadow-lg hover:shadow-lg shadow-purple-300 hover:shadow-purple-500 hover:ring-2 ring-offset-2 ring-purple-500"
|
|
>
|
|
<DonationIcon />
|
|
Spenden
|
|
</a>
|
|
<div
|
|
class="hidden xl:flex form-control flex-row items-center gap-2 tooltip tooltip-accent"
|
|
data-tip="Füge das Lufrai Logo zu deinem Dokument hinzu."
|
|
>
|
|
<input
|
|
id="welcome-modal-show-watermark"
|
|
checked={localState.showLufraiWatermark}
|
|
class="checkbox checkbox-lg checkbox-accent shadow-md"
|
|
type="checkbox"
|
|
onClick={(evt) =>
|
|
setLocalState("showLufraiWatermark", evt.currentTarget.checked)
|
|
}
|
|
/>
|
|
<label
|
|
for="welcome-modal-show-watermark"
|
|
class="btn btn-sm btn-accent gap-2 shadow-md"
|
|
>
|
|
<WatermarkIcon />
|
|
Für Lufrai werben
|
|
</label>
|
|
</div>
|
|
<button
|
|
onClick={() => setLocalState("showWelcome", false)}
|
|
class="hidden xl:flex btn btn-xl btn-primary gap-2 transition-all shadow-lg hover:shadow-lg shadow-indigo-300 hover:shadow-indigo-500 hover:ring-2 ring-offset-2 ring-indigo-500"
|
|
>
|
|
<LaunchIcon />
|
|
Loslegen
|
|
</button>
|
|
<div class="w-full text-sm xl:hidden bg-error bg-opacity-50 ring-2 ring-offset-2 ring-error text-error-content rounded p-3 shadow-2xl flex items-center justify-center gap-3">
|
|
<WarningIcon /> Bitte verwende einen Laptop oder Computer!
|
|
</div>
|
|
</div>
|
|
<a
|
|
href="https://git.lufrai.com/rappli/rappli/src/branch/master/CHANGELOG.md#changelog"
|
|
class="hover:underline absolute bottom-8 right-8 text-xs text-black opacity-60 flex gap-3"
|
|
{...externalLink}
|
|
>
|
|
<span>Version: {__APP_VERSION__}</span>
|
|
<span>{getDisplayDate(new Date(__BUILD_TIME__))}</span>
|
|
</a>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default WelcomeModal;
|