From b0a5e4770c372f74e3818519f35cb4e9b4fd94f0 Mon Sep 17 00:00:00 2001 From: JobvAlewijk Date: Tue, 30 Dec 2025 20:56:05 +0100 Subject: [PATCH] feat: improved visuals and structure ref: N25B-402 --- .../SimpleProgram/SimpleProgram.module.css | 167 ++++++++++++++ src/pages/SimpleProgram/SimpleProgram.tsx | 206 +++++++++++------- 2 files changed, 293 insertions(+), 80 deletions(-) create mode 100644 src/pages/SimpleProgram/SimpleProgram.module.css diff --git a/src/pages/SimpleProgram/SimpleProgram.module.css b/src/pages/SimpleProgram/SimpleProgram.module.css new file mode 100644 index 0000000..69cc65c --- /dev/null +++ b/src/pages/SimpleProgram/SimpleProgram.module.css @@ -0,0 +1,167 @@ +/* ---------- Layout ---------- */ + +.container { + height: 100%; + display: flex; + flex-direction: column; + background: #1e1e1e; + color: #f5f5f5; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: clamp(0.75rem, 2vw, 1.25rem); + background: #2a2a2a; + border-bottom: 1px solid #3a3a3a; +} + +.header h2 { + font-size: clamp(1rem, 2.2vw, 1.4rem); + font-weight: 600; +} + +.controls button { + margin-left: 0.5rem; + padding: 0.4rem 0.9rem; + border-radius: 6px; + border: none; + background: #111; + color: white; + cursor: pointer; +} + +.controls button:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +/* ---------- Content ---------- */ + +.content { + flex: 1; + padding: 2%; +} + +/* ---------- Grid ---------- */ + +.phaseGrid { + height: 100%; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-rows: repeat(2, minmax(0, 1fr)); + gap: 2%; +} + +/* ---------- Box ---------- */ + +.box { + display: flex; + flex-direction: column; + background: #ffffff; + color: #1e1e1e; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25); +} + +.boxHeader { + padding: 0.6rem 0.9rem; + background: linear-gradient(135deg, #dcdcdc, #e9e9e9); + font-style: italic; + font-weight: 500; + font-size: clamp(0.9rem, 1.5vw, 1.05rem); + border-bottom: 1px solid #cfcfcf; +} + +.boxContent { + flex: 1; + padding: 0.8rem 1rem; + overflow-y: auto; +} + +/* ---------- Lists ---------- */ + +.iconList { + list-style: none; + padding: 0; + margin: 0; +} + +.iconList li { + display: flex; + align-items: center; + gap: 0.6rem; + margin-bottom: 0.5rem; + font-size: clamp(0.85rem, 1.3vw, 1rem); +} + +.bulletList { + margin: 0; + padding-left: 1.2rem; +} + +.bulletList li { + margin-bottom: 0.4rem; +} + +/* ---------- Icons ---------- */ + +.successIcon, +.failIcon { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 1.5rem; + height: 1.5rem; + border-radius: 4px; + font-weight: bold; + color: white; + flex-shrink: 0; +} + +.successIcon { + background: #3cb371; +} + +.failIcon { + background: #e5533d; +} + +/* ---------- Empty ---------- */ + +.empty { + opacity: 0.55; + font-style: italic; + font-size: 0.9rem; +} + +/* ---------- Responsive ---------- */ + +@media (max-width: 900px) { + .phaseGrid { + grid-template-columns: 1fr; + grid-template-rows: repeat(4, minmax(0, 1fr)); + gap: 1rem; + } +} + +.leftControls { + display: flex; + align-items: center; + gap: 1rem; +} + +.backButton { + background: transparent; + border: 1px solid #555; + color: #ddd; + padding: 0.35rem 0.75rem; + border-radius: 6px; + cursor: pointer; +} + +.backButton:hover { + background: #333; +} diff --git a/src/pages/SimpleProgram/SimpleProgram.tsx b/src/pages/SimpleProgram/SimpleProgram.tsx index b682b1a..d548108 100644 --- a/src/pages/SimpleProgram/SimpleProgram.tsx +++ b/src/pages/SimpleProgram/SimpleProgram.tsx @@ -1,7 +1,7 @@ import React from "react"; -import styles from "../VisProgPage/VisProg.module.css"; +import styles from "./SimpleProgram.module.css"; -/* ---------- Types (mirrors backend / reducer output) ---------- */ +/* ---------- Types ---------- */ type Norm = { id: string; @@ -40,95 +40,141 @@ type SimpleProgramProps = { phases: Phase[]; }; +/* ---------- Reusable UI ---------- */ -/* ---------- Component ---------- */ +type BoxProps = { + title: string; + children: React.ReactNode; +}; +const Box: React.FC = ({ title, children }) => ( +
+
{title}
+
{children}
+
+); + +/* ---------- Lists ---------- */ + +const GoalList: React.FC<{ goals: Goal[] }> = ({ goals }) => { + if (goals.length === 0) return

No goals defined.

; -/** - * SimpleProgram - * - * Read-only oversight view for a reduced program. - * Displays norms, goals, and triggers grouped per phase. - */ -const SimpleProgram: React.FC = ({ phases }) => { return ( -
-

Simple Program Overview

- - {phases.map((phase) => ( -
-

{phase.label}

+ ← Back + +

+ Phase {phaseIndex + 1} / {phases.length}: {phase.label} +

- {/* Norms */} -
-

Norms

- {phase.norms.length === 0 ? ( -

No norms defined.

- ) : ( -
    - {phase.norms.map((norm) => ( -
  • - {norm.label}: {norm.norm} -
  • - ))} -
- )} -
+
+ - {/* Goals */} -
-

Goals

- {phase.goals.length === 0 ? ( -

No goals defined.

- ) : ( -
    - {phase.goals.map((goal) => ( -
  • - {goal.label}: {goal.description}{" "} - - [{goal.achieved ? "✔" : "❌"}] - -
  • - ))} -
- )} -
- - {/* Triggers */} -
-

Triggers

- {phase.triggers.length === 0 ? ( -

No triggers defined.

- ) : ( -
    - {phase.triggers.map((trigger) => ( -
  • - {trigger.label} ({trigger.type}) -
      - {trigger.keywords.map((kw) => ( -
    • {kw.keyword}
    • - ))} -
    -
  • - ))} -
- )} -
+
- ))} + +
+ +
+
); };