Skip to content

Commit

Permalink
Vaardigheden (#17)
Browse files Browse the repository at this point in the history
* Finished "vaardighedenkompas"
  • Loading branch information
marlonbaeten authored Sep 16, 2024
1 parent 7a9161e commit f1b66d6
Show file tree
Hide file tree
Showing 10 changed files with 2,083 additions and 158 deletions.
3 changes: 3 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
<path fill="#fff" d="M8 2h16v4h-16v-4z"></path>
<path fill="#fff" d="M30 8h-28c-1.1 0-2 0.9-2 2v10c0 1.1 0.9 2 2 2h6v8h16v-8h6c1.1 0 2-0.9 2-2v-10c0-1.1-0.9-2-2-2zM4 14c-1.105 0-2-0.895-2-2s0.895-2 2-2 2 0.895 2 2-0.895 2-2 2zM22 28h-12v-10h12v10z"></path>
</symbol>
<symbol id="icon-marker" viewBox="0 0 512 512">
<path d="M451.47 125.404l-70.904-70.902a13.11 13.11 0 00-17.746-.733L164.999 221.372l119.603 119.602 167.6-197.822a13.11 13.11 0 00-.733-17.748zM116.153 267.658l29.002-29.001 122.16 122.16-29.001 29.002zM94.552 363.73l47.69 47.69c18.523-11.008 40.65-15.58 63.161-17.391l-93.46-93.46c-1.811 22.511-6.383 44.638-17.39 63.162zm-35.938 39.898a6.574 6.574 0 00-1.273 7.501l22.375 46.487a6.575 6.575 0 0010.572 1.796l31.411-31.41-43.728-43.73z" />
</symbol>
</defs>
</svg>
<div id="root"></div>
Expand Down
25 changes: 21 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import Results from './Results';
import Skills from './Skills';
import Table from './Table';
import usePersistence from './usePersistence';
import { copyLink, saveStateLocal } from './util';
import voha from './voha.jpg';

export default function App() {
const { state, select, mark, note } = usePersistence();
const { state, select, mark, note, selectSkill, markSkill, noteSkill, navigate } = usePersistence();

if (state.skillMode) {
return (
<Skills
state={state}
navigate={navigate}
selectSkill={selectSkill}
markSkill={markSkill}
noteSkill={noteSkill}
/>
);
}

return (
<>
Expand Down Expand Up @@ -35,14 +48,18 @@ export default function App() {
</ol>
<p>
<strong>Markeren</strong> kan door het vakje rechts te selecteren.
<br />
Dit mag je gebruiken als je hier bijvoorbeeld extra aandacht aan wilt
besteden of een vraag over hebt.
<br />
Onder aan de pagina verschijnt een lijst van gemarkeerde items.
</p>
</div>

<p className="actions">
<button onClick={() => navigate(true)}>
Vaardighedenkompas
</button>
</p>

<Table state={state} select={select} mark={mark} />
<hr />
<Results state={state} mark={mark} note={note} />
Expand All @@ -55,7 +72,7 @@ export default function App() {
Je kunt ook een link kopiëren en deze ergens veilige bewaren,
of een bestand downloaden en deze op een veilige plek opslaan.
</p>
<p className="save">
<p className="actions">
<button onClick={() => saveStateLocal(state)}>
<svg>
<use xlinkHref="#icon-floppy-disk" />
Expand Down
39 changes: 39 additions & 0 deletions src/SkillMarked.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { SkillCategory, SkillGroup, State } from './usePersistence';

interface SkillMarkedProps {
state: State;
mark: (index: number, marked: boolean) => void;
}

export default function SkillMarked({ state, mark }: SkillMarkedProps) {
const items = state.skills
.map((skillCategory: SkillCategory) => skillCategory.groups
.map((skillGroup: SkillGroup) =>
skillGroup.items.map((item) => {
if (!item.marked) {
return null;
}

return (
<li key={item.name}>
<input
type="checkbox"
name={`check-${item.index}`}
checked={true}
onChange={() => mark(item.index, false)}
aria-label="Verwijderen"
/>
{item.name}
</li>
);
})
))
.flat()
.filter((item) => item !== null);

if (items.length === 0) {
return <p>Nog geen gemarkeerde vaardigheden</p>;
}

return <ul>{items}</ul>;
}
104 changes: 104 additions & 0 deletions src/SkillTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Fragment } from 'preact/jsx-runtime';
import { State } from './usePersistence';

interface SkillTableProps {
state: State;
select: (index: number, value: boolean|null) => void;
mark: (index: number, marked: boolean) => void;
}

export default function SkillTable({ state, select, mark }: SkillTableProps) {
return (
<table className="form skills">
<thead>
<tr>
<th colSpan={3} style={{ border: 'none' }}></th>
<th>
<label data-tooltip="onvoldoende ervaring">O</label>
</th>
<th>
<label data-tooltip="voldoende ervaring">V</label>
</th>
<th data-tooltip="markeren" role="columnheader">
<svg>
<use xlinkHref="#icon-marker" />
</svg>
</th>
</tr>
</thead>
<tbody>
{state.skills.map((category) => (
<Fragment key={category.name}>
<tr>
<td colSpan={6} className="white"></td>
</tr>
<tr>
<th
colSpan={6}
className="skillCategory"
>
Lijst vaardigheden: {category.name}
</th>
</tr>
{category.groups.map((group) => (
<Fragment key={group.name}>
<tr>
<th className="skillGroup"
colSpan={6}>{group.name}</th>
</tr>
{group.items.map((item, index) => (
<tr className="selectable" key={item.name}>
<th scope="row">{index + 1}</th>
<td className="skill-grade">
<label data-tooltip={item.basic === null ? '*' : (item.basic ? 'Basisvaardigheid' : 'Facultatieve vaardigheid')}>
{item.basic === null ? '*' : (item.basic ? 'B' : 'F')}
</label>
</td>
<td className="skill-name">{item.name}</td>
<td>
<label data-tooltip="onvoldoende ervaring">
<input
type="radio"
name={`skill-option-${item.index}`}
id={`skill-option-${item.index}-0`}
checked={item.value === false}
onChange={() => select(item.index, false)}
aria-label={"onvoldoende ervaring"}
/>
</label>
</td>
<td>
<label data-tooltip="voldoende ervaring">
<input
type="radio"
name={`skill-option-${item.index}`}
id={`skill-option-${item.index}-1`}
checked={item.value === true}
onChange={() => select(item.index, true)}
aria-label={"voldoende ervaring"}
/>
</label>
</td>
<td data-tooltip="markeren" role="columnheader">
<label htmlFor={`check-${item.index}`} data-tooltip="markeren">
<input
type="checkbox"
id={`check-${item.index}`}
name={`check-${item.index}`}
onChange={(e) => mark(item.index, (e.target as HTMLInputElement).checked)}
checked={item.marked}
aria-label="markeren"
/>
</label>
</td>
</tr>
)
)}
</Fragment>
))}
</Fragment>
))}
</tbody>
</table>
);
}
108 changes: 108 additions & 0 deletions src/Skills.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import SkillMarked from './SkillMarked';
import SkillTable from './SkillTable';
import { State } from './usePersistence';
import { copyLink, saveStateLocal } from './util';
import voha from './voha.jpg';

interface SkillsProps {
state: State;
navigate: (skillMode: boolean) => void;
selectSkill: (index: number, value: boolean|null) => void;
markSkill: (index: number, marked: boolean) => void;
noteSkill: (content: string) => void;
}

export default function Skills({ state, selectSkill, markSkill, navigate, noteSkill }: SkillsProps) {
return (
<>
<header>
<div>
<h1>Vaardighedenkompas</h1>
<p>
Overzicht vaardigheden per ICPC-categorie
</p>
</div>
<div>
<img src={voha} alt="Vervolgopleiding tot huisarts" />
</div>
</header>

<div className="legenda">
<h2>Legenda</h2>
<p>
<code>O</code> = Onvoldoende ervaring<br />
<code>V</code> = Voldoende ervaring
</p>
<p>
<code>B</code> = Basisvaardigheid<br />
<code>F</code> = Facultatieve vaardigheid
</p>
<p>
<code>*</code> = Ten tijde van de inventarisatie om het huidige overzicht in te delen,
ontbrak het onderdeel 'palliatieve en terminale zorg' in dit overzicht en is dus
niet meegenomen in de indeling. In 2024 vindt een herijking van deze lijst plaats,
dan zal het onderdeel 'palliatieve en terminale zorg' meegenomen worden.
</p>
</div>

<p className="actions">
<button onClick={() => navigate(false)}>
Ervaringskompas
</button>
</p>

<SkillTable state={state} select={selectSkill} mark={markSkill} />

<h2>Gemarkeerde vaardigheden</h2>

<SkillMarked state={state} mark={markSkill} />

<hr />

<h2>Notities</h2>
<textarea
value={state.skillNotes}
onChange={(event) => noteSkill((event.target as HTMLTextAreaElement).value)}
aria-label="Notities"
rows={state.skillNotes.split(/\r\n|\r|\n/).length}
/>
<div className="print-notes">
{state.skillNotes.split('\n').map((item, key) => (
<p key={key}>
{item}
</p>
))}
</div>

<div className="save-section">
<hr />
<h2>Opslaan</h2>
<p>
Om je ingevulde gegevens te bewaren heb je twee opties.
Als je op een persoonlijk apparaat werkt kun je de huidige toestand opslaan in je browser.
Je kunt ook een link kopiëren en deze ergens veilige bewaren.
</p>
<p className="actions">
<button onClick={() => saveStateLocal(state)}>
<svg>
<use xlinkHref="#icon-floppy-disk" />
</svg>
Opslaan in de browser
</button>
<button onClick={() => copyLink(state)}>
<svg>
<use xlinkHref="#icon-link" />
</svg>
Unieke link kopiëren
</button>
<button onClick={() => window.print()}>
<svg>
<use xlinkHref="#icon-printer" />
</svg>
Printen
</button>
</p>
</div>
</>
);
}
4 changes: 2 additions & 2 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export default function Table({ state, select, mark }: TableProps) {
</th>
))}
<th data-tooltip="markeren" role="columnheader">
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="M451.47 125.404l-70.904-70.902a13.11 13.11 0 00-17.746-.733L164.999 221.372l119.603 119.602 167.6-197.822a13.11 13.11 0 00-.733-17.748zM116.153 267.658l29.002-29.001 122.16 122.16-29.001 29.002zM94.552 363.73l47.69 47.69c18.523-11.008 40.65-15.58 63.161-17.391l-93.46-93.46c-1.811 22.511-6.383 44.638-17.39 63.162zm-35.938 39.898a6.574 6.574 0 00-1.273 7.501l22.375 46.487a6.575 6.575 0 0010.572 1.796l31.411-31.41-43.728-43.73z" />
<svg>
<use xlinkHref="#icon-marker" />
</svg>
</th>
</tr>
Expand Down
Loading

0 comments on commit f1b66d6

Please sign in to comment.