Skip to content

Commit

Permalink
Add Milestone component
Browse files Browse the repository at this point in the history
- corresponds to slides 14 & 15 from MONDEY-Neu-Design_28-08-24
- use Breadcrumb for backwards navigation instead of multiple "zurück" links
- each answer button has a different shade of green as background colour
- mouseover tooltips for answer buttons match colour of answer button
- vertical layout on small screens, horizontal on large screens
- checkbox to automatically go to the next question without having to click weiter
- förderhilfen is in an Accordian - initially hidden
- add temporary /milestone route to demo the component
  - add temporary baby images for demo
  • Loading branch information
lkeegan committed Sep 4, 2024
1 parent ca7d7fb commit 1605cbd
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 0 deletions.
Binary file added src/lib/assets/baby0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/baby1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/baby2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/baby3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/lib/components/Childrenpage.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

<script context="module">
export function convertData(rawdata) {
let data = rawdata.map((item) => {
Expand Down
110 changes: 110 additions & 0 deletions src/lib/components/Milestone.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<script lang="ts">
import {P, Breadcrumb, BreadcrumbItem, AccordionItem, Accordion, Button, Checkbox} from 'flowbite-svelte';
import {QuestionCircleSolid, ArrowRightOutline, HomeOutline} from 'flowbite-svelte-icons'
import MilestoneButton from "$lib/components/MilestoneButton.svelte";
export let data;
let currentMilestoneIndex: number = 0;
let selectedAnswer: number | null = data.milestones[currentMilestoneIndex].answer;
let autoGoToNextMilestone: boolean = false;
// build list of possible image urls at build time to be able to dynamically use them at run time:
const images: Record<string, string> = import.meta.glob('$lib/assets/*.jpg', {
eager: true,
query: '?url',
import: 'default'
});
function firstMilestone() {
console.log("firstMilestone: clearing selected answer, setting current index to 0");
selectedAnswer = null;
currentMilestoneIndex = 0;
}
function nextMilestone() {
if (selectedAnswer === null) {
console.log("nextMilestone: No answer selected, ignoring");
}
console.log(`nextMilestone: Submitting answer ${selectedAnswer} for milestone ${currentMilestoneIndex}`);
data.milestones[currentMilestoneIndex].answer = selectedAnswer;
// todo: API call to submit answer?
if (currentMilestoneIndex + 1 == data.milestones.length) {
console.log(`nextMilestone: Last milestone complete`)
// todo: redirect to bereichuebersicht?
return;
}
currentMilestoneIndex += 1;
console.log(`nextMilestone: currentMilestoneIndex = ${currentMilestoneIndex}`);
selectedAnswer = data.milestones[currentMilestoneIndex].answer;
}
function selectAnswer(answer: number | null) {
console.log(`selectAnswer: answer ${answer} selected for milestone ${currentMilestoneIndex}`);
selectedAnswer = answer;
if (selectedAnswer !== null && autoGoToNextMilestone) {
console.log(`selectAnswer: calling nextMilestone`);
nextMilestone();
}
}
</script>

<div class="flex flex-col bg-white border border-1 border-gray-200 rounded-lg shadow dark:border-gray-700 dark:bg-gray-800 md:max-w-5xl">
<div class="bg-gray-100 dark:bg-gray-600">
<Breadcrumb olClass="inline-flex items-center space-x-1 rtl:space-x-reverse md:space-x-3 rtl:space-x-reverse flex-wrap" navClass="m-2">
<BreadcrumbItem href="#" home>Start</BreadcrumbItem>
<BreadcrumbItem href="#">MEIKE</BreadcrumbItem>
<BreadcrumbItem href="#">Bereichübersicht</BreadcrumbItem>
<!-- reload below is a temporary hack for demo purposes -->
<BreadcrumbItem href="javascript:window.location.reload(true)">{data.title}</BreadcrumbItem>
<BreadcrumbItem>{currentMilestoneIndex + 1} / {data.milestones.length}</BreadcrumbItem>
</Breadcrumb>
</div>
<div>
<div class="w-full flex flex-col md:flex-row">
<img class="object-cover h-48 md:h-96 md:rounded-bl-lg w-full md:w-64 lg:w-96"
src={images[`/src/lib/assets/${data.milestones[currentMilestoneIndex].img}`]} alt="">
<div class="m-2 md:m-4">
<h2 class="mb-2 text-2xl font-bold text-gray-700 dark:text-gray-400">{data.milestones[currentMilestoneIndex].title}</h2>
<P>{data.milestones[currentMilestoneIndex].desc}</P>
<Accordion flush>
<AccordionItem>
<span slot="header" class="text-base flex gap-2">
<QuestionCircleSolid class="mt-0.5"/>
<span>Förderhilfen</span>
</span>
<P>
{data.milestones[currentMilestoneIndex].help}
</P>
</AccordionItem>
</Accordion>
</div>
<div class="flex flex-col justify-items-stretch rounded-lg m-1">
<MilestoneButton color="green-50" selected={selectedAnswer===0} onClick={() => {selectAnswer(0)}}
tooltip="Das Kind macht noch keine Anstalten bzw. ist noch nicht in der Lage, das Verhalten auszuführen.">
Noch gar nicht
</MilestoneButton>
<MilestoneButton color="green-100" selected={selectedAnswer===1} onClick={() => {selectAnswer(1)}}
tooltip="Das Kind zeigt erste Ansätze, das Verhalten auszuführen, weicht dabei aber noch erheblich von der Beschreibung ab oder/und ist sehr unsicher.">
In Ansätzen
</MilestoneButton>
<MilestoneButton color="green-200" selected={selectedAnswer===2} onClick={() => {selectAnswer(2)}}
tooltip="Das Kind beherrscht das Verhalten im Prinzip, zeigt es aber erst selten, ist dabei noch leicht unsicher oder führt es nicht ganz sauber aus.">
Weitgehend
</MilestoneButton>
<MilestoneButton color="green-400" selected={selectedAnswer===3} onClick={() => {selectAnswer(3)}}
tooltip="Das Kind zeigt das Verhalten mehrmals sicher und genau wie beschrieben.">
Zuverlässig
</MilestoneButton>
<Button color="light" disabled={selectedAnswer === null} on:click={nextMilestone} class="m-1 mt-4">
Weiter
<ArrowRightOutline class="w-5 h-5 ms-2"/>
</Button>
<Checkbox class="m-1" bind:checked={autoGoToNextMilestone}>
<P class="text-xs">Automatisch weiter</P>
</Checkbox>
</div>
</div>
</div>
</div>
18 changes: 18 additions & 0 deletions src/lib/components/MilestoneButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
import {Tooltip} from 'flowbite-svelte';
export let selected: boolean = false;
export let color: string = 'white-900';
export let tooltip: string = '';
export let onClick: () => {};
let bg_color = `bg-${color}`;
</script>

<button type="button" on:click={onClick}
class={`${bg_color} ${selected ? 'opacity-100 outline-none ring-4 ring-blue-400' : 'opacity-50 hover:opacity-80'} border border-gray-200 rounded-lg font-medium border-1 px-5 py-3 m-1 md:my-2 text-center`}>
<slot />
</button>
<Tooltip class={`${bg_color} text-gray-700 dark:${bg_color} dark:text-gray-700`}>
{tooltip}
</Tooltip>
47 changes: 47 additions & 0 deletions src/routes/milestone/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script>
// Demo page for Milestone component
import Milestone from '$lib/components/Milestone.svelte';
const data = {
"title": "Grobmotorik",
"desc": " Hier geht es darum, zu beschreiben, wie sich das Kind fortbewegt Und seinen Körper (Rumpf, Arme, Beine) kontrollieren kann.",
"milestones": [
{
"number": 1,
"title": "Alleine von Stufe/Absatz springen",
"desc": "Kind springt mit beiden Beinen gleichzeitig hoch und überwindet im Sprung freihändig einen (kleinen) Absatz oder eine Stufe. Es kommt sicher wieder im Stand auf.",
"help": "Beim Treppengehen im Haus, beim Spazierengehen oder auf dem Spielplatz bieten sich vielfältige Gelegenheiten, Kinder zum Springen von einem Absatz (z.B. einem höheren Bordstein. einem Holzstamm, oder einem Stein) zu ermutigen. Machen Sie Ihrem Kind die Bewegung vor oder führen Sie sie gemeinsam mit dem Kind durch. Nehmen Sie das Kind dafür zunächst bei an die Hand. Später können sie die Hand immer lockerer mitführen und die Eigenbewegung des Kindes nur noch passiv begleiten. So kann das Kind am besten selbst herausfinden, wie es seine Arme einsetzen muss, um Schwung zu holen und beim Landen das Gleichgewicht zu finden. Ist das Springen an der Hand sicher, lösen Sie die Hand ganz und stellen Sie sich gegenüber dem Kind hin, damit es weiß, dass es im Notfall aufgefangen wird.",
"img": "baby0.jpg",
"answer": null
},
{
"number": 2,
"title": "Das Köpfchen alleine heben",
"desc": "Kind liegt auf dem Bauch, hält die Arme angewinkelt neben dem Körper und hebt sein Köpfchen aus eigener Kraft so hoch, dass das Kinn nicht mehr die Auflage berührt. Diese Position kann es mehr als 3 Sekunden halten.",
"help": "Help text goes here",
"img": "baby1.jpg",
"answer": null
},
{
"number": 3,
"title": "Den Kopf frei bewegen",
"desc": "Kind kann seinen Kopf frei halten und bewegen, wenn es z.B. auf dem Schoß sitzt. Wenn man seinen Körper ein wenig schräg hält, gleicht es diese Bewegung mit dem Kopf aus. Der Kopf wackelt kaum oder gar nicht, wenn das Kind ihn dreht.",
"help": "Help text goes here",
"img": "baby2.jpg",
"answer": null
},
{
"number": 4,
"title": "Sich in Bauchlage mit gestreckten Armen aufstützen",
"desc": "Kind liegt auf dem Bauch. Es stützt sich mit beiden Armen gestreckt von der Unterlage ab und hebt seinen Rücken an, um den Kopf aufrecht zu halten. Schultern und Brust liegen für mehr als 3 Sekunden nicht mehr auf der Unterlage.",
"help": "Help text goes here",
"img": "baby3.jpg",
"answer": null
}
]
}
</script>

<div class="flex justify-center items-center">
<Milestone data={data}/>
</div>
6 changes: 6 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export default {
'./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'
],
darkMode: 'selector',
safelist: [
'bg-green-50',
'bg-green-100',
'bg-green-200',
'bg-green-400',
],
theme: {
extend: {
colors: {
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
Expand Down

0 comments on commit 1605cbd

Please sign in to comment.