import { useState } from 'react';
const DecisionTree = () => {
// Tree structure based on the flowchart
const tree = {
// First question: ziekte, etc.
root: {
type: "question",
text: "Heeft de ontbindende voorwaarde betrekking op ziekte van de werknemer, bedrijfseconomische redenen, zwangerschap of huwelijk?",
yesNode: "niet_rechtsgeldig_1",
noNode: "check_objectief_bepaalbaar"
},
// Results for first branch
niet_rechtsgeldig_1: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig op grond van art. 7:667 lid 7 en 8 BW. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "Art. 7:677 lid 7 en 8 BW."
},
// Second question: objectief bepaalbaar
check_objectief_bepaalbaar: {
type: "question",
text: "Is het intreden van de ontbindende voorwaarde objectief bepaalbaar, dat wil zeggen een concreet moment of gebeurtenis?",
explanation: "De vraag of de ontbindende voorwaarde is ingetreden, moet objectief bepaalbaar zijn en mag dus niet afhangen van een subjectief oordeel van werkgever.",
yesNode: "check_werkgever_invloed",
noNode: "niet_rechtsgeldig_2"
},
// Results for second branch
niet_rechtsgeldig_2: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "De vraag of de ontbindende voorwaarde is ingetreden, moet objectief bepaalbaar zijn en mag dus niet afhangen van een subjectief oordeel van werkgever."
},
// Third question: werkgever invloed
check_werkgever_invloed: {
type: "question",
text: "Heeft de werkgever zelf invloed gehad op het intreden van de ontbindende voorwaarde?",
yesNode: "niet_rechtsgeldig_3",
noNode: "info_mogelijk_met_risico"
},
// Results for third branch
niet_rechtsgeldig_3: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "Een ontbindende voorwaarde moet gekoppeld zijn aan een toekomstige, onzekere gebeurtenis. Nu werkgever invloed heeft gehad op het intreden van de ontbindende voorwaarde is dit niet het geval en is de ontbindende voorwaarde niet rechtsgeldig."
},
// Information about possible risk
info_mogelijk_met_risico: {
type: "info",
title: "Informatie:",
text: "Een beroep op een ontbindende voorwaarde is mogelijk, met als risico dat door de werknemer herstel of een billijke vergoeding wordt gevorderd op grond van art. 7:682 BW wegens strijd met art. 7:671b BW. Ontbinding is mogelijk een 'veiligere' keuze.",
explanation: "Art. 7:682 BW, art. 7:671b BW\nHet is niet duidelijk of een einde van rechtswege van de arbeidsovereenkomst door een ontbindende voorwaarde nog mogelijk is onder het huidig ontslagrecht. Werknemer kan zich beroepen op de ongeldigheid van de ontbindende voorwaarde en binnen twee maanden een verzoek tot vernietiging van de opzegging (met bijkomende loonvordering) of tot toekenning van een billijke vergoeding indienen bij de kantonrechter. Werkgever kan er daarom voor kiezen toch een ontbindingsverzoek in te dienen.",
nextNode: "check_ernstig_verwijtbaar"
},
// Fourth question: ernstig verwijtbaar
check_ernstig_verwijtbaar: {
type: "question",
text: "Heeft de werknemer ernstig verwijtbaar gehandeld?",
yesNode: "ontslag_staande_voet",
noNode: "check_verwijtbaar_handelen"
},
// Results for fourth branch
ontslag_staande_voet: {
type: "result",
title: "Conclusie:",
text: "Ontslag op staande voet of ontbinding op grond van art. 7:669 lid 3 sub e BW ligt het meest voor de hand.",
explanation: "Art. 7:669 lid 3 sub e BW\nLet op:\n- Mogelijk hoeft geen transitievergoeding te worden betaald, tenzij niet redelijk;\n- Er geldt geen herplaatsingsplicht;\n- Bij een ontslag op staande voet geldt geen opzegtermijn en bij sub e wordt de opzegtermijn in de rechtspraak vaak verkort."
},
// Fifth question: verwijtbaar handelen
check_verwijtbaar_handelen: {
type: "question",
text: "Is wel sprake van verwijtbaar handelen/nalaten?",
yesNode: "ontbinding_sub_e",
noNode: "check_herplaatsing"
},
// Results for fifth branch
ontbinding_sub_e: {
type: "result",
title: "Conclusie:",
text: "Ontbinding op grond van art. 7:669 lid 3 sub e BW ligt het meest voor de hand.",
explanation: "Art. 7:669 lid 3 sub e BW\nLet op:\n- Er geldt geen herplaatsingsplicht;\n- Werknemer heeft (als is voldaan aan de vereisten) recht op een transitievergoeding;\n- Bij sub e wordt de opzegtermijn in de rechtspraak vaak verkort."
},
// Sixth question: herplaatsing
check_herplaatsing: {
type: "question",
text: "Is herplaatsing van de werknemer mogelijk (en kan dit van de werkgever worden verlangd)?",
yesNode: "herplaatsing_verplicht",
noNode: "ontbinding_sub_d_of_h"
},
// Results for sixth branch
herplaatsing_verplicht: {
type: "result",
title: "Conclusie:",
text: "Werknemer moet worden herplaatst. Ontbinding is niet mogelijk.",
explanation: "Nu herplaatsing mogelijk is, zal werknemer op de passende functie moeten worden geplaatst. Ontbinding is (nog) niet mogelijk. Art. 7:669 lid 3 BW"
},
// Results for final branch
ontbinding_sub_d_of_h: {
type: "result",
title: "Conclusie:",
text: "Ontbinding op grond van art. 7:669 lid 3 sub d of h BW ligt het meest voor de hand. Is sprake van meer dan één mogelijke grond voor ontslag? Dan kan per 1 januari 2020 misschien worden ontbonden op de cumulatiegrond (artikel 7:669 lid 3 sub i BW). Werkgever heeft wel een herplaatsingsplicht en moet rekening houden met de geldende opzegtermijn.",
explanation: "Art. 7:669 lid 3 sub d of h BW\nBij een verband tussen het functioneren van werknemer en de ontbindende voorwaarde kan gedacht worden aan de d-grond. Een ontbindende voorwaarde inhoudende dat de arbeidsovereenkomst eindigt wanneer de arbeidsovereenkomst inhoudsloos is geworden, kan een h-grond opleveren als geen sprake is van disfunctioneren of verwijtbaar handelen/nalaten van werknemer. Let op: de h-grond mag niet worden gebruikt voor het repareren van andere onvoldragen gronden."
}
};
// Track current node and history
const [currentNodeId, setCurrentNodeId] = useState('root');
const [history, setHistory] = useState([]);
const [path, setPath] = useState(['root']); // Track full path for back functionality
// Get current node
const currentNode = tree[currentNodeId];
// Handle answers
const handleAnswer = (isYes) => {
// Only add to history if it's a question
if (currentNode.type === "question") {
setHistory([...history, {
question: currentNode.text,
answer: isYes ? 'Ja' : 'Nee'
}]);
}
// Determine next node
let nextNodeId;
if (currentNode.type === "info") {
nextNodeId = currentNode.nextNode;
} else {
nextNodeId = isYes ? currentNode.yesNode : currentNode.noNode;
}
// Go to next node and update path
if (nextNodeId) {
setCurrentNodeId(nextNodeId);
setPath([...path, nextNodeId]);
}
};
// Go back one step
const goBack = () => {
if (path.length > 1) {
// Remove current node from path
const newPath = [...path];
newPath.pop();
// Set current node to previous node
const previousNodeId = newPath[newPath.length - 1];
setCurrentNodeId(previousNodeId);
setPath(newPath);
// Remove last entry from history if we're going back from a question
if (currentNode.type === "question" || currentNode.type === "info") {
const newHistory = [...history];
newHistory.pop();
setHistory(newHistory);
}
}
};
// Reset the tree
const resetTree = () => {
setCurrentNodeId('root');
setHistory([]);
};
return (
<div className="flex flex-col items-center w-full max-w-4xl mx-auto p-6 bg-white rounded-lg shadow-lg">
<h1 className="text-2xl font-bold text-blue-800 mb-6">Beslisboom Ontbindende Voorwaarde in Arbeidsrecht</h1>
{/* History section */}
{history.length > 0 && (
<div className="w-full mb-6 p-4 bg-gray-50 rounded-lg">
<h2 className="font-semibold text-gray-700 mb-2">Voorgaande vragen:</h2>
<ul className="space-y-1">
{history.map((item, index) => (
<li key={index} className="text-sm">
<span className="font-medium">{item.question}</span>
<span className={item.answer === 'Ja' ? 'text-green-600 ml-2' : 'text-red-600 ml-2'}>
{item.answer}
</span>
</li>
))}
</ul>
</div>
)}
{/* Current node display */}
<div className="w-full mb-6 p-6 bg-blue-50 rounded-lg border border-blue-200">
{currentNode.type === "result" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">{currentNode.title}</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<>
<h3 className="text-lg font-semibold text-blue-700 mb-2">Toelichting:</h3>
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</>
)}
</>
)}
{currentNode.type === "info" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">{currentNode.title}</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-sm">
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</div>
)}
<div className="flex justify-center space-x-4">
<button
onClick={() => handleAnswer(true)}
className="px-6 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500"
>
Doorgaan
</button>
{path.length > 1 && currentNodeId !== 'root' && (
<button
onClick={goBack}
className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-400"
>
Stap terug
</button>
)}
</div>
</>
)}
{currentNode.type === "question" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">Vraag:</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-sm">
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</div>
)}
<div className="flex justify-center space-x-4">
<button
onClick={() => handleAnswer(true)}
className="px-6 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500"
>
Ja
</button>
<button
onClick={() => handleAnswer(false)}
className="px-6 py-2 bg-red-600 text-white font-medium rounded-lg hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500"
>
Nee
</button>
{path.length > 1 && (
<button
onClick={goBack}
className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-400"
>
Stap terug
</button>
)}
</div>
</>
)}
</div>
{/* Reset button */}
{(history.length > 0 || currentNode.type === "result") && (
<button
onClick={resetTree}
className="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
>
Opnieuw beginnen
</button>
)}
</div>
);
};
export default DecisionTree;
const DecisionTree = () => {
// Tree structure based on the flowchart
const tree = {
// First question: ziekte, etc.
root: {
type: "question",
text: "Heeft de ontbindende voorwaarde betrekking op ziekte van de werknemer, bedrijfseconomische redenen, zwangerschap of huwelijk?",
yesNode: "niet_rechtsgeldig_1",
noNode: "check_objectief_bepaalbaar"
},
// Results for first branch
niet_rechtsgeldig_1: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig op grond van art. 7:667 lid 7 en 8 BW. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "Art. 7:677 lid 7 en 8 BW."
},
// Second question: objectief bepaalbaar
check_objectief_bepaalbaar: {
type: "question",
text: "Is het intreden van de ontbindende voorwaarde objectief bepaalbaar, dat wil zeggen een concreet moment of gebeurtenis?",
explanation: "De vraag of de ontbindende voorwaarde is ingetreden, moet objectief bepaalbaar zijn en mag dus niet afhangen van een subjectief oordeel van werkgever.",
yesNode: "check_werkgever_invloed",
noNode: "niet_rechtsgeldig_2"
},
// Results for second branch
niet_rechtsgeldig_2: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "De vraag of de ontbindende voorwaarde is ingetreden, moet objectief bepaalbaar zijn en mag dus niet afhangen van een subjectief oordeel van werkgever."
},
// Third question: werkgever invloed
check_werkgever_invloed: {
type: "question",
text: "Heeft de werkgever zelf invloed gehad op het intreden van de ontbindende voorwaarde?",
yesNode: "niet_rechtsgeldig_3",
noNode: "info_mogelijk_met_risico"
},
// Results for third branch
niet_rechtsgeldig_3: {
type: "result",
title: "Conclusie:",
text: "De ontbindende voorwaarde is niet rechtsgeldig. Werkgever moet een redelijke grond voor ontslag hebben.",
explanation: "Een ontbindende voorwaarde moet gekoppeld zijn aan een toekomstige, onzekere gebeurtenis. Nu werkgever invloed heeft gehad op het intreden van de ontbindende voorwaarde is dit niet het geval en is de ontbindende voorwaarde niet rechtsgeldig."
},
// Information about possible risk
info_mogelijk_met_risico: {
type: "info",
title: "Informatie:",
text: "Een beroep op een ontbindende voorwaarde is mogelijk, met als risico dat door de werknemer herstel of een billijke vergoeding wordt gevorderd op grond van art. 7:682 BW wegens strijd met art. 7:671b BW. Ontbinding is mogelijk een 'veiligere' keuze.",
explanation: "Art. 7:682 BW, art. 7:671b BW\nHet is niet duidelijk of een einde van rechtswege van de arbeidsovereenkomst door een ontbindende voorwaarde nog mogelijk is onder het huidig ontslagrecht. Werknemer kan zich beroepen op de ongeldigheid van de ontbindende voorwaarde en binnen twee maanden een verzoek tot vernietiging van de opzegging (met bijkomende loonvordering) of tot toekenning van een billijke vergoeding indienen bij de kantonrechter. Werkgever kan er daarom voor kiezen toch een ontbindingsverzoek in te dienen.",
nextNode: "check_ernstig_verwijtbaar"
},
// Fourth question: ernstig verwijtbaar
check_ernstig_verwijtbaar: {
type: "question",
text: "Heeft de werknemer ernstig verwijtbaar gehandeld?",
yesNode: "ontslag_staande_voet",
noNode: "check_verwijtbaar_handelen"
},
// Results for fourth branch
ontslag_staande_voet: {
type: "result",
title: "Conclusie:",
text: "Ontslag op staande voet of ontbinding op grond van art. 7:669 lid 3 sub e BW ligt het meest voor de hand.",
explanation: "Art. 7:669 lid 3 sub e BW\nLet op:\n- Mogelijk hoeft geen transitievergoeding te worden betaald, tenzij niet redelijk;\n- Er geldt geen herplaatsingsplicht;\n- Bij een ontslag op staande voet geldt geen opzegtermijn en bij sub e wordt de opzegtermijn in de rechtspraak vaak verkort."
},
// Fifth question: verwijtbaar handelen
check_verwijtbaar_handelen: {
type: "question",
text: "Is wel sprake van verwijtbaar handelen/nalaten?",
yesNode: "ontbinding_sub_e",
noNode: "check_herplaatsing"
},
// Results for fifth branch
ontbinding_sub_e: {
type: "result",
title: "Conclusie:",
text: "Ontbinding op grond van art. 7:669 lid 3 sub e BW ligt het meest voor de hand.",
explanation: "Art. 7:669 lid 3 sub e BW\nLet op:\n- Er geldt geen herplaatsingsplicht;\n- Werknemer heeft (als is voldaan aan de vereisten) recht op een transitievergoeding;\n- Bij sub e wordt de opzegtermijn in de rechtspraak vaak verkort."
},
// Sixth question: herplaatsing
check_herplaatsing: {
type: "question",
text: "Is herplaatsing van de werknemer mogelijk (en kan dit van de werkgever worden verlangd)?",
yesNode: "herplaatsing_verplicht",
noNode: "ontbinding_sub_d_of_h"
},
// Results for sixth branch
herplaatsing_verplicht: {
type: "result",
title: "Conclusie:",
text: "Werknemer moet worden herplaatst. Ontbinding is niet mogelijk.",
explanation: "Nu herplaatsing mogelijk is, zal werknemer op de passende functie moeten worden geplaatst. Ontbinding is (nog) niet mogelijk. Art. 7:669 lid 3 BW"
},
// Results for final branch
ontbinding_sub_d_of_h: {
type: "result",
title: "Conclusie:",
text: "Ontbinding op grond van art. 7:669 lid 3 sub d of h BW ligt het meest voor de hand. Is sprake van meer dan één mogelijke grond voor ontslag? Dan kan per 1 januari 2020 misschien worden ontbonden op de cumulatiegrond (artikel 7:669 lid 3 sub i BW). Werkgever heeft wel een herplaatsingsplicht en moet rekening houden met de geldende opzegtermijn.",
explanation: "Art. 7:669 lid 3 sub d of h BW\nBij een verband tussen het functioneren van werknemer en de ontbindende voorwaarde kan gedacht worden aan de d-grond. Een ontbindende voorwaarde inhoudende dat de arbeidsovereenkomst eindigt wanneer de arbeidsovereenkomst inhoudsloos is geworden, kan een h-grond opleveren als geen sprake is van disfunctioneren of verwijtbaar handelen/nalaten van werknemer. Let op: de h-grond mag niet worden gebruikt voor het repareren van andere onvoldragen gronden."
}
};
// Track current node and history
const [currentNodeId, setCurrentNodeId] = useState('root');
const [history, setHistory] = useState([]);
const [path, setPath] = useState(['root']); // Track full path for back functionality
// Get current node
const currentNode = tree[currentNodeId];
// Handle answers
const handleAnswer = (isYes) => {
// Only add to history if it's a question
if (currentNode.type === "question") {
setHistory([...history, {
question: currentNode.text,
answer: isYes ? 'Ja' : 'Nee'
}]);
}
// Determine next node
let nextNodeId;
if (currentNode.type === "info") {
nextNodeId = currentNode.nextNode;
} else {
nextNodeId = isYes ? currentNode.yesNode : currentNode.noNode;
}
// Go to next node and update path
if (nextNodeId) {
setCurrentNodeId(nextNodeId);
setPath([...path, nextNodeId]);
}
};
// Go back one step
const goBack = () => {
if (path.length > 1) {
// Remove current node from path
const newPath = [...path];
newPath.pop();
// Set current node to previous node
const previousNodeId = newPath[newPath.length - 1];
setCurrentNodeId(previousNodeId);
setPath(newPath);
// Remove last entry from history if we're going back from a question
if (currentNode.type === "question" || currentNode.type === "info") {
const newHistory = [...history];
newHistory.pop();
setHistory(newHistory);
}
}
};
// Reset the tree
const resetTree = () => {
setCurrentNodeId('root');
setHistory([]);
};
return (
<div className="flex flex-col items-center w-full max-w-4xl mx-auto p-6 bg-white rounded-lg shadow-lg">
<h1 className="text-2xl font-bold text-blue-800 mb-6">Beslisboom Ontbindende Voorwaarde in Arbeidsrecht</h1>
{/* History section */}
{history.length > 0 && (
<div className="w-full mb-6 p-4 bg-gray-50 rounded-lg">
<h2 className="font-semibold text-gray-700 mb-2">Voorgaande vragen:</h2>
<ul className="space-y-1">
{history.map((item, index) => (
<li key={index} className="text-sm">
<span className="font-medium">{item.question}</span>
<span className={item.answer === 'Ja' ? 'text-green-600 ml-2' : 'text-red-600 ml-2'}>
{item.answer}
</span>
</li>
))}
</ul>
</div>
)}
{/* Current node display */}
<div className="w-full mb-6 p-6 bg-blue-50 rounded-lg border border-blue-200">
{currentNode.type === "result" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">{currentNode.title}</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<>
<h3 className="text-lg font-semibold text-blue-700 mb-2">Toelichting:</h3>
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</>
)}
</>
)}
{currentNode.type === "info" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">{currentNode.title}</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-sm">
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</div>
)}
<div className="flex justify-center space-x-4">
<button
onClick={() => handleAnswer(true)}
className="px-6 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500"
>
Doorgaan
</button>
{path.length > 1 && currentNodeId !== 'root' && (
<button
onClick={goBack}
className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-400"
>
Stap terug
</button>
)}
</div>
</>
)}
{currentNode.type === "question" && (
<>
<h2 className="text-xl font-bold text-blue-800 mb-4">Vraag:</h2>
<p className="text-gray-800 mb-6">{currentNode.text}</p>
{currentNode.explanation && (
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-sm">
<p className="text-gray-700 whitespace-pre-line">{currentNode.explanation}</p>
</div>
)}
<div className="flex justify-center space-x-4">
<button
onClick={() => handleAnswer(true)}
className="px-6 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500"
>
Ja
</button>
<button
onClick={() => handleAnswer(false)}
className="px-6 py-2 bg-red-600 text-white font-medium rounded-lg hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500"
>
Nee
</button>
{path.length > 1 && (
<button
onClick={goBack}
className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-400"
>
Stap terug
</button>
)}
</div>
</>
)}
</div>
{/* Reset button */}
{(history.length > 0 || currentNode.type === "result") && (
<button
onClick={resetTree}
className="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
>
Opnieuw beginnen
</button>
)}
</div>
);
};
export default DecisionTree;