Benutzung von Solid JS Store um Zustand über den Komponentnebaum zu teilen.

This commit is contained in:
Marco Kittel 2025-06-18 07:51:14 +02:00
parent 33ba07f306
commit 5b8acc026d
4 changed files with 124 additions and 23 deletions

View File

@ -1,13 +1,45 @@
import type { Component } from 'solid-js';
import { createStore } from 'solid-js/store'
import logo from './logo.svg';
import styles from './App.module.css';
import { CalendarComponent } from './Calendar';
import { DiaryComponent } from './Diary';
import { ProgressComponent } from './Progress';
export const [store, setStore] = createStore({
calendarClick: new Date(),
localDate: Date.now(),
userCount: 3,
users: [
{
id: 0,
username: "felix909",
location: "England",
loggedIn: false,
},
{
id: 1,
username: "tracy634",
location: "Canada",
loggedIn: true,
},
{
id: 2,
username: "johny123",
location: "India",
loggedIn: true,
},
],
})
const App: Component = () => {
return (
<>
<ProgressComponent/>
<CalendarComponent/>
<DiaryComponent/>
</>
);

View File

@ -1,12 +1,12 @@
import { For, createSignal, Show } from 'solid-js';
import { store, setStore } from './App';
function getDateArray(year: number, month: number, startday: number) {
//Das bedeutet Montag im englischen Wochenformat.
const startTagDerWoche = startday;
const offsetZumEnglischenSonntag = (7 - startTagDerWoche);
const wochenTagDesErsten = (new Date(year, month, 1).getDay() + offsetZumEnglischenSonntag) % 7;
const wochenTage = [{"dayname":"So", "dayInWeekArr":0}, {"dayname":"Mo", "dayInWeekArr":1}, {"dayname":"Di", "dayInWeekArr":2}, {"dayname":"Mi", "dayInWeekArr":3}, {"dayname":"Do", "dayInWeekArr":4}, {"dayname":"Fr", "dayInWeekArr":5}, {"dayname":"Sa", "dayInWeekArr":6}];
const wochenTage = [{ "dayname": "So", "dayInWeekArr": 0 }, { "dayname": "Mo", "dayInWeekArr": 1 }, { "dayname": "Di", "dayInWeekArr": 2 }, { "dayname": "Mi", "dayInWeekArr": 3 }, { "dayname": "Do", "dayInWeekArr": 4 }, { "dayname": "Fr", "dayInWeekArr": 5 }, { "dayname": "Sa", "dayInWeekArr": 6 }];
const monatsNamen = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
const wochenTageNachAnfangsTag = [];
for (let i = startTagDerWoche; i < startTagDerWoche + 7; i++) {
@ -18,17 +18,18 @@ function getDateArray(year: number, month: number, startday: number) {
} else {
const vorMonatTage = new Date(year, month, 0).getDate();
for (let i = wochenTagDesErsten - 1; i >= 0; i--) {
const tagObj = { "value": vorMonatTage - i, "enabled": false }
const tagObj = { "value": vorMonatTage - i, "enabled": false, "date": new Date() }
tage.push(tagObj);
}
}
for (let i = 1; i <= new Date(year, month + 1, 0).getDate(); i++) {
const tagObj = { "value": i, "enabled": true }
console.log(i);
const tagObj = { "value": i, "enabled": true, "date": new Date(year, month, i, 10,0) }
tage.push(tagObj);
}
let nextDay = 1;
for (let i = tage.length; i < 42; i++) {
const tagObj = { "value": nextDay, "enabled": false }
const tagObj = { "value": nextDay, "enabled": false, "date": new Date() }
tage.push(tagObj);
nextDay++;
}
@ -36,11 +37,11 @@ function getDateArray(year: number, month: number, startday: number) {
}
export function CalendarComponent() {
const [month, setMonth] = createSignal(0);
const [year, setYear] = createSignal(2025);
const [startDay, setStartday] = createSignal(1);
const [month, setMonth] = createSignal(new Date(store.localDate).getMonth());
const [year, setYear] = createSignal(new Date(store.localDate).getFullYear());
const [startDay, setStartday] = createSignal(new Date(store.localDate).getDate());
let onclickDayOfWeekHeader = (day : number) => {
let onclickDayOfWeekHeader = (day: number) => {
setStartday(day);
}
@ -53,6 +54,14 @@ export function CalendarComponent() {
setMonth(month() + 1);
};
let onclickDayOfMonth = (day: Date) => {
setStore("calendarClick", day);
}
let getSelectedDay = () => {
return store.calendarClick.getDate();
}
let onclickPrevMonth = () => {
if (month() <= 0) {
setMonth(11);
@ -66,7 +75,7 @@ export function CalendarComponent() {
<div class="w-full max-w-sm mx-auto">
<div class="text-center grid grid-cols-7">
<For each={getDateArray(year(), month(), startDay()).weekDay}>
{(day) => <div><button onclick={()=> onclickDayOfWeekHeader(day.dayInWeekArr)}>{day.dayname}</button></div>}
{(day) => <div><button onclick={() => onclickDayOfWeekHeader(day.dayInWeekArr)}>{day.dayname}</button></div>}
</For>
</div>
<div
@ -74,19 +83,17 @@ export function CalendarComponent() {
<For each={getDateArray(year(), month(), startDay()).days}>
{(day) =>
<Show when={day.enabled}
fallback={
<div class="bg-white">
<button type="button" class="flex items-center justify-center w-full mx-auto size-10 text-base-500 text-gray-400"
>
<time datetime="#_">{day.value}</time>
</button>
</div>
}
fallback={
<div class="bg-white">
<button type="button" class="flex items-center justify-center w-full mx-auto size-10 text-base-500 text-gray-400"
>
<time datetime="#_">{day.value}</time>
</button>
</div>
}
>
<div class="bg-amber-100">
<button type="button" class="flex items-center justify-center w-full mx-auto size-10 text-base-500 hover:text-blue-600"
<div class={getSelectedDay() === day.value ? "bg-amber-200": "bg-amber-100"}>
<button type="button" onclick={() => onclickDayOfMonth(day.date)} class="flex items-center justify-center w-full mx-auto size-10 text-base-500 hover:text-blue-600"
>
<time datetime="#_">{day.value}</time>
</button>
@ -98,7 +105,7 @@ export function CalendarComponent() {
<div class="flex items-center mt-4">
<h2 class="flex-auto text-sm font-medium text-black">{getDateArray(year(), month(),startDay()).month} {getDateArray(year(), month(), startDay()).year}</h2>
<h2 class="flex-auto text-sm font-medium text-black">{getDateArray(year(), month(), startDay()).month} {getDateArray(year(), month(), startDay()).year}</h2>
<div class="flex items-center gap-1">
<button
type="button"
@ -145,6 +152,7 @@ export function CalendarComponent() {
</button>
</div>
</div>
</div >
)
}

10
src/Diary.tsx Normal file
View File

@ -0,0 +1,10 @@
import { store, setStore } from './App';
export function DiaryComponent(){
return (
<>
<div>
{store.calendarClick.toUTCString()}
</div>
</>
);
}

51
src/Progress.tsx Normal file
View File

@ -0,0 +1,51 @@
export function ProgressComponent() {
return (
<div class="grid-rows-1 grid-cols-2 inline-flex3 bg-amber-50 mx-auto inline-flex w-max">
<div class="relative flex items-center h-18 p-4 m-4 bg-amber-300 text-amber-300 border-b-1 w-50">
<div class="inline-flex items-center">
<label class="flex items-center cursor-pointer relative">
<input type="checkbox" class="peer h-6 w-6 cursor-pointer transition-all appearance-none rounded-full bg-slate-100 shadow hover:shadow-md border border-slate-300 checked:bg-slate-800 checked:border-slate-800" id="check-custom-style" />
<span class="absolute text-white opacity-0 peer-checked:opacity-100 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" viewBox="0 0 20 20" fill="currentColor" stroke="currentColor" stroke-width="1">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
</span>
</label>
</div>
<span class="px-4 text-black">1. Schritt</span>
<svg
class="absolute left-full h-full w-4 text-amber-300"
viewBox="0 0 20 40"
preserveAspectRatio="none"
>
<path d="M0,0 L20,20 L0,40 Z" fill="currentColor" />
</svg>
</div>
<div class="p-4 m-4 inline-flex "></div>
<div class="relative flex items-center h-18 p-4 m-4 bg-amber-300 text-amber-300 border-b-1 w-50">
<div class="inline-flex items-center">
<label class="flex items-center cursor-pointer relative">
<input type="checkbox" class="peer h-6 w-6 cursor-pointer transition-all appearance-none rounded-full bg-slate-100 shadow hover:shadow-md border border-slate-300 checked:bg-slate-800 checked:border-slate-800" id="check-custom-style" />
<span class="absolute text-white opacity-0 peer-checked:opacity-100 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" viewBox="0 0 20 20" fill="currentColor" stroke="currentColor" stroke-width="1">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
</span>
</label>
</div>
<span class="px-4 text-black">2. Schritt</span>
<svg
class="absolute left-full h-full w-4 text-amber-300"
viewBox="0 0 20 40"
preserveAspectRatio="none"
>
<path d="M0,0 L20,20 L0,40 Z" fill="currentColor" />
</svg>
</div>
</div>
)
}