From d7508ad5cf0baf0b8602faf6b17720ef56f9e72c Mon Sep 17 00:00:00 2001 From: Labibatanjim Date: Mon, 18 May 2026 06:07:36 +1000 Subject: [PATCH 1/3] feat(dashboard): improve dashboard list item UI --- package-lock.json | 1 + .../dashboard-list-item.component.html | 361 +++++++++++++++- .../dashboard-list-item.component.scss | 393 +++++++++++++++++- 3 files changed, 735 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e16479f5..6954d4375 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11213,6 +11213,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ diff --git a/src/app/dashboard/dashboard-list-item.component.html b/src/app/dashboard/dashboard-list-item.component.html index ef5bd52e5..283111c53 100644 --- a/src/app/dashboard/dashboard-list-item.component.html +++ b/src/app/dashboard/dashboard-list-item.component.html @@ -1,8 +1,353 @@ -
-

{{ task?.title }}

- -
- Task {{ task?.number }} - {{ task?.type }} -
-
\ No newline at end of file + + + + + + OnTrack + + + + + + + + + +
+ + +
+
+ SIT101 + + + +
+
+ + +
+
+
+
+

Task Name

+ 2 +
+
+ 1.1P - Pass Task + ⌛ 1d +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task +
+
+

Working On It

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

+

Submit by Thu 16 Apr

+
+ + + +
+
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #4 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + ⌛ 1w +
+
+
+
+ +
+
+ + +
+
+ SIT102 + + + +
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task +
+
+
+
+ + +
+
+
+
+

Task Name

+ !! +
+
+ 1.1P - Pass Task + #2 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+ !! +
+
+ 1.1P - Pass Task + #1 + ⌛ 1d +
+
+
+
+ + +
+
+
+
+

Task Name

+ 2 +
+
+ 1.1P - Pass Task + #6 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #7 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #5 + ⌛ 1w +
+
+
+
+ +
+
+ + +
+
+ SIT103 + + + +
+
+ + +
+
+
+
+

Task Name

+ !! + 2 +
+
+ 1.1P - Pass Task + ⌛ 1d +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #3 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #8 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #9 + ⌛ 1w +
+
+
+
+ + +
+
+
+
+

Task Name

+
+
+ 1.1P - Pass Task + #10 + ⌛ 1w +
+
+
+
+ +
+
+ +
+ + + + + diff --git a/src/app/dashboard/dashboard-list-item.component.scss b/src/app/dashboard/dashboard-list-item.component.scss index 463fb3471..be3a5a0bc 100644 --- a/src/app/dashboard/dashboard-list-item.component.scss +++ b/src/app/dashboard/dashboard-list-item.component.scss @@ -1,22 +1,391 @@ +// ---- Variables ---- +$brand-indigo : #3730d8; +$white : #ffffff; +$gray-50 : #f9fafb; +$gray-100 : #f3f4f6; +$gray-200 : #e5e7eb; +$gray-400 : #9ca3af; +$gray-500 : #6b7280; +$gray-700 : #374151; +$gray-900 : #111827; + +$red : #ef4444; +$orange : #f97316; +$green : #22c55e; +$teal : #14b8a6; +$blue : #3b82f6; + +$font-stack : 'Segoe UI', system-ui, -apple-system, sans-serif; +$radius-sm : 4px; +$radius-md : 6px; +$radius-lg : 8px; +$shadow-card : 0 2px 8px rgba(0, 0, 0, 0.10); + +// ---- Reset ---- +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: $font-stack; + background: $gray-100; + min-height: 100vh; + color: $gray-900; +} + +button { + font-family: $font-stack; + cursor: pointer; +} + +// ============================================================ +// NAVBAR +// ============================================================ +.navbar { + background: $white; + height: 64px; + padding: 0 24px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid $gray-200; + position: sticky; + top: 0; + z-index: 100; + + &__logo { + display: flex; + align-items: center; + } + + &__avatar { + width: 36px; + height: 36px; + border-radius: 50%; + background: $gray-200; + color: $gray-700; + font-size: 13px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background 0.15s; + + &:hover { background: $gray-400; } + } +} + +// ============================================================ +// BOARD (horizontal scroll container) +// ============================================================ +.board { + display: flex; + gap: 20px; + padding: 28px 24px; + overflow-x: auto; + align-items: flex-start; + min-height: calc(100vh - 64px); +} + +// ============================================================ +// COLUMN +// ============================================================ +.column { + flex: 0 0 340px; + min-width: 280px; + border-radius: $radius-lg; + overflow: hidden; + box-shadow: $shadow-card; + background: $white; + display: flex; + flex-direction: column; + + // ---- Header bar ---- + &__header { + background: $brand-indigo; + padding: 14px 16px; + display: flex; + align-items: center; + gap: 10px; + } + + &__title { + color: $white; + font-weight: 800; + font-size: 18px; + letter-spacing: 0.5px; + margin-right: 4px; + white-space: nowrap; + } + + &__search { + flex: 1; + padding: 5px 10px; + border-radius: $radius-md; + border: none; + font-size: 13px; + background: rgba($white, 0.18); + color: $white; + outline: none; + font-family: $font-stack; + transition: background 0.15s; + + &::placeholder { color: rgba($white, 0.65); } + &:focus { background: rgba($white, 0.28); } + } + + &__icon-btn { + background: none; + border: none; + padding: 2px; + display: flex; + align-items: center; + opacity: 0.85; + border-radius: $radius-sm; + transition: opacity 0.15s; + + &:hover { opacity: 1; } + } + + // ---- Scrollable task list ---- + &__body { + flex: 1; + overflow-y: auto; + background: $gray-50; + max-height: calc(100vh - 130px); + + // Thin scrollbar + scrollbar-width: thin; + scrollbar-color: $gray-200 transparent; + + &::-webkit-scrollbar { width: 4px; } + &::-webkit-scrollbar-track { background: transparent; } + &::-webkit-scrollbar-thumb { background: $gray-200; border-radius: 2px; } + } +} + +// ============================================================ +// TASK ITEM — your existing structure +// ============================================================ .task-item { - padding: 12px; - border-radius: 8px; - background: white; + display: flex; + align-items: stretch; // makes task-color fill full height + background: $white; + margin-bottom: 1px; + transition: background 0.1s; + + &:hover { background: $gray-50; } + + // ---- Expanded state ---- + &--expanded { + .task-expanded-body { display: block; } + .task-arrow { transform: rotate(180deg); } + } +} + +// ============================================================ +// TASK COLOR BAR (left accent stripe) +// ============================================================ +.task-color { + width: 4px; + flex-shrink: 0; + border-radius: 0; // flush, no rounding on single-side border + + &--orange { background: $orange; } + &--green { background: $green; } + &--blue { background: $blue; } + &--teal { background: $teal; } + &--gray { background: $gray-400; } +} + +// ============================================================ +// TASK CONTENT +// ============================================================ +.task-content { + flex: 1; + min-width: 0; + padding: 10px 10px 10px 14px; +} + +// ---- Header row (title + alert badges) ---- +.task-header { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; cursor: pointer; - margin-bottom: 10px; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + user-select: none; - &:hover { - background: #f5f5f5; + h4 { + font-size: 14px; + font-weight: 600; + color: $gray-900; + flex: 1; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } } +// ---- Details row (subtext, priority badge, time) ---- .task-details { display: flex; - justify-content: space-between; - font-size: 12px; + align-items: center; + flex-wrap: wrap; + gap: 5px; + font-size: 13px; + color: $gray-500; +} + +// ---- Time indicator ---- +.task-time { + font-size: 13px; + color: $gray-500; +} + +// ============================================================ +// TASK ALERT (circular badge — top-right of header) +// .task-alert--comment → plain number (red circle) +// .task-alert--blocked → !! (red circle, larger) +// ============================================================ +.task-alert { + display: inline-flex; + align-items: center; + justify-content: center; + font-weight: 700; + color: $white; + flex-shrink: 0; + border-radius: 50%; + + &--comment { + width: 22px; + height: 22px; + font-size: 11px; + background: $red; + } + + &--blocked { + width: 26px; + height: 26px; + font-size: 12px; + background: $red; + } +} + +// ============================================================ +// TASK BADGE (pill — inside .task-details row) +// .task-badge--red → priority 1–2 +// .task-badge--orange → priority 3–5 +// .task-badge--gray → priority 6+ +// ============================================================ +.task-badge { + display: inline-flex; + align-items: center; + justify-content: center; + font-weight: 700; + font-size: 11px; + color: $white; + border-radius: 10px; + padding: 0 6px; + min-width: 22px; + height: 18px; + flex-shrink: 0; + + &--red { background: $red; } + &--orange { background: $orange; } + &--gray { background: $gray-400; } +} + +// ============================================================ +// TASK ARROW (collapse/expand chevron) +// ============================================================ +.task-arrow { + display: flex; + align-items: flex-start; + padding: 12px 12px 0 4px; + font-size: 20px; + color: $gray-500; + flex-shrink: 0; + line-height: 1; + transition: transform 0.2s ease; + cursor: pointer; + user-select: none; + + // Flips when expanded (via JS toggling task-item--expanded, + // or directly via task-arrow--up) + &--up { transform: rotate(180deg); } +} + +// ============================================================ +// EXPANDED BODY (hidden by default, shown when --expanded) +// ============================================================ +.task-expanded-body { + display: none; + margin-top: 10px; + padding-top: 12px; + border-top: 1px solid $gray-100; +} + +.task-working-on { + font-weight: 700; + font-size: 14px; + color: $gray-900; + margin-bottom: 6px; +} + +.task-description { + font-size: 14px; + color: $gray-700; + line-height: 1.6; + margin-bottom: 10px; +} + +.task-due { + font-size: 14px; + color: $gray-700; + margin-bottom: 14px; + + strong { font-weight: 700; } } -.task-type { - font-weight: bold; -} \ No newline at end of file +.task-btns { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.task-btn { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 6px 12px; + border-radius: $radius-md; + border: 1px solid $gray-200; + background: $white; + font-size: 13px; + color: $gray-700; + transition: background 0.15s, border-color 0.15s; + + &:hover { + background: $gray-50; + border-color: $gray-400; + } +} + +// ============================================================ +// RESPONSIVE +// ============================================================ +@media (max-width: 768px) { + .board { + padding: 16px 12px; + gap: 14px; + } + + .column { + flex: 0 0 300px; + } +} From fd7bac6edcf384a28b101e820a70bef21b5482ab Mon Sep 17 00:00:00 2001 From: Labibatanjim Date: Tue, 19 May 2026 00:34:29 +1000 Subject: [PATCH 2/3] fix: add class body and Input properties to component --- .../dashboard-list-item.component.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/app/dashboard/dashboard-list-item.component.ts b/src/app/dashboard/dashboard-list-item.component.ts index b201cfcad..04edd0d2f 100644 --- a/src/app/dashboard/dashboard-list-item.component.ts +++ b/src/app/dashboard/dashboard-list-item.component.ts @@ -1,17 +1,24 @@ -import {Component, Input} from '@angular/core'; - -export type DashboardTask = { - title: string; - subtitle: string; - abbreviation: string; - color: string; - comments: number; -}; +import { Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'f-dashboard-list-item', templateUrl: './dashboard-list-item.component.html', + styleUrl: './dashboard-list-item.component.scss', + standalone: true, + imports: [CommonModule], }) export class DashboardListItemComponent { - @Input() task: DashboardTask; -} + @Input() taskName: string = 'Task Name'; + @Input() taskLabel: string = '1.1P - Pass Task'; + @Input() color: string = 'gray'; + @Input() alertType: string = ''; + @Input() alertCount: number = 0; + @Input() badge: string = ''; + @Input() badgeColor: string = 'gray'; + @Input() time: string = ''; + @Input() description: string = ''; + @Input() dueDate: string = ''; + + expanded: boolean = false; +} \ No newline at end of file From 933a60a12c8cfae2f2bc6d3e1a7b5cb65f20f330 Mon Sep 17 00:00:00 2001 From: Labibatanjim Date: Tue, 19 May 2026 01:10:30 +1000 Subject: [PATCH 3/3] fix: update component template and class to match DashboardTask interface --- .../dashboard-list-item.component.html | 368 +----------------- .../dashboard-list-item.component.ts | 25 +- 2 files changed, 32 insertions(+), 361 deletions(-) diff --git a/src/app/dashboard/dashboard-list-item.component.html b/src/app/dashboard/dashboard-list-item.component.html index 283111c53..b94847ac9 100644 --- a/src/app/dashboard/dashboard-list-item.component.html +++ b/src/app/dashboard/dashboard-list-item.component.html @@ -1,353 +1,23 @@ - - - - - - OnTrack - - - - - - - - - -
- - -
-
- SIT101 - - - -
-
- - -
-
-
-
-

Task Name

- 2 -
-
- 1.1P - Pass Task - ⌛ 1d -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task -
-
-

Working On It

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

-

Submit by Thu 16 Apr

-
- - - -
-
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #4 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - ⌛ 1w -
-
-
-
- -
-
- - -
-
- SIT102 - - - -
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task -
-
-
-
- - -
-
-
-
-

Task Name

- !! -
-
- 1.1P - Pass Task - #2 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

- !! -
-
- 1.1P - Pass Task - #1 - ⌛ 1d -
-
-
-
- - -
-
-
-
-

Task Name

- 2 -
-
- 1.1P - Pass Task - #6 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #7 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #5 - ⌛ 1w -
-
-
-
- -
+
+ {{ subtitle }} + {{ abbreviation }}
- - -
-
- SIT103 - - - -
-
- - -
-
-
-
-

Task Name

- !! - 2 -
-
- 1.1P - Pass Task - ⌛ 1d -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #3 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #8 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #9 - ⌛ 1w -
-
-
-
- - -
-
-
-
-

Task Name

-
-
- 1.1P - Pass Task - #10 - ⌛ 1w -
-
-
-
- +
+

Working On It

+

Submit by {{ subtitle }}

+
+ + +
- -
- - - - - + +
+ \ No newline at end of file diff --git a/src/app/dashboard/dashboard-list-item.component.ts b/src/app/dashboard/dashboard-list-item.component.ts index 04edd0d2f..b3476159d 100644 --- a/src/app/dashboard/dashboard-list-item.component.ts +++ b/src/app/dashboard/dashboard-list-item.component.ts @@ -1,24 +1,25 @@ import { Component, Input } from '@angular/core'; import { CommonModule } from '@angular/common'; +export interface DashboardTask { + title: string; + subtitle: string; + abbreviation: string; + color: string; + comments: number; +} + @Component({ selector: 'f-dashboard-list-item', templateUrl: './dashboard-list-item.component.html', styleUrl: './dashboard-list-item.component.scss', - standalone: true, - imports: [CommonModule], }) export class DashboardListItemComponent { - @Input() taskName: string = 'Task Name'; - @Input() taskLabel: string = '1.1P - Pass Task'; + @Input() title: string = 'Task Name'; + @Input() subtitle: string = '1.1P - Pass Task'; + @Input() abbreviation: string = ''; @Input() color: string = 'gray'; - @Input() alertType: string = ''; - @Input() alertCount: number = 0; - @Input() badge: string = ''; - @Input() badgeColor: string = 'gray'; - @Input() time: string = ''; - @Input() description: string = ''; - @Input() dueDate: string = ''; + @Input() comments: number = 0; expanded: boolean = false; -} \ No newline at end of file +}