add dashboard calendar week strip; styles
This commit is contained in:
@@ -957,7 +957,7 @@ export function App() {
|
||||
<header className="catalog-header">
|
||||
<div className="catalog-brand">
|
||||
<span className="catalog-logo">Plant-Man</span>
|
||||
<span className="catalog-subtitle">Plant Care Supply</span>
|
||||
<span className="catalog-subtitle">Plant care workbench</span>
|
||||
</div>
|
||||
<div className="catalog-contact">
|
||||
<strong>{plants.length}</strong>
|
||||
@@ -967,7 +967,7 @@ export function App() {
|
||||
|
||||
<div className="catalog-layout">
|
||||
<aside className="catalog-sidebar">
|
||||
<h2>Concepts</h2>
|
||||
<h2>Workbench</h2>
|
||||
<nav className="catalog-nav" aria-label="Primary navigation">
|
||||
<div className="nav-group">
|
||||
<h3>Operations</h3>
|
||||
@@ -1297,7 +1297,7 @@ function getViewTitle(view: View) {
|
||||
case 'flags':
|
||||
return 'Plant Flags';
|
||||
default:
|
||||
return 'Plant-Man';
|
||||
return 'Dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { CalendarCheck, Plus } from 'lucide-react';
|
||||
import type { CareTask, Plant } from '../domain';
|
||||
import { PlantCard } from './PlantCard';
|
||||
@@ -26,6 +27,10 @@ export function HomeView({
|
||||
onOpenPlant,
|
||||
}: HomeViewProps) {
|
||||
const dueTaskGroups = groupDueTasks(careTasks);
|
||||
const weekDays = useMemo(() => getWeekDays(), []);
|
||||
const [selectedDate, setSelectedDate] = useState(() => weekDays[0]?.dateKey ?? getDateKey(new Date()));
|
||||
const selectedDay = weekDays.find((day) => day.dateKey === selectedDate) ?? weekDays[0];
|
||||
const selectedTasks = getTasksForDate(careTasks, selectedDate);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -39,6 +44,62 @@ export function HomeView({
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section" aria-labelledby="calendar-heading">
|
||||
<div className="section-heading">
|
||||
<h2 id="calendar-heading">Care Calendar</h2>
|
||||
<span className="schedule-count">{selectedTasks.length} selected</span>
|
||||
</div>
|
||||
|
||||
<div className="week-strip" role="tablist" aria-label="Care tasks by day">
|
||||
{weekDays.map((day) => {
|
||||
const dayTasks = getTasksForDate(careTasks, day.dateKey);
|
||||
const hasDueTasks = dayTasks.some((task) => task.status === 'due');
|
||||
|
||||
return (
|
||||
<button
|
||||
className="week-day"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={day.dateKey === selectedDate}
|
||||
key={day.dateKey}
|
||||
onClick={() => setSelectedDate(day.dateKey)}
|
||||
>
|
||||
<span>{day.label}</span>
|
||||
<strong>{day.dayNumber}</strong>
|
||||
<small>{dayTasks.length}</small>
|
||||
{hasDueTasks ? <span className="week-day-alert" aria-hidden="true" /> : null}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="task-list">
|
||||
<p className="task-list-label">{selectedDay?.heading ?? 'Selected day'}</p>
|
||||
{!isLoading && selectedTasks.length === 0 ? (
|
||||
<p className="empty-state">No care scheduled for this day.</p>
|
||||
) : null}
|
||||
|
||||
{selectedTasks.map((task) => (
|
||||
<article className="task-row" key={`calendar-${task.id}`}>
|
||||
<span className={`status-dot ${task.status}`} />
|
||||
<div>
|
||||
<h3>{task.action}</h3>
|
||||
<p>{task.plantName} - {task.due}</p>
|
||||
</div>
|
||||
<button
|
||||
className="small-action"
|
||||
type="button"
|
||||
disabled={task.status !== 'due'}
|
||||
onClick={() => onCompleteTask(task)}
|
||||
>
|
||||
<CalendarCheck size={16} />
|
||||
Log
|
||||
</button>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section" aria-labelledby="care-heading">
|
||||
<div className="section-heading">
|
||||
<h2 id="care-heading">Due Care</h2>
|
||||
@@ -153,3 +214,64 @@ function formatPlantNames(tasks: CareTask[]) {
|
||||
|
||||
return `${names.slice(0, 3).join(', ')} + ${names.length - 3} more`;
|
||||
}
|
||||
|
||||
function getWeekDays() {
|
||||
const today = new Date();
|
||||
|
||||
return Array.from({ length: 7 }, (_, index) => {
|
||||
const date = new Date(today);
|
||||
date.setDate(today.getDate() + index);
|
||||
const dateKey = getDateKey(date);
|
||||
|
||||
return {
|
||||
dateKey,
|
||||
dayNumber: date.getDate().toString(),
|
||||
heading: index === 0
|
||||
? 'Today'
|
||||
: date.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' }),
|
||||
label: index === 0
|
||||
? 'Today'
|
||||
: date.toLocaleDateString(undefined, { weekday: 'short' }),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getTasksForDate(tasks: CareTask[], dateKey: string) {
|
||||
const todayKey = getDateKey(new Date());
|
||||
|
||||
return tasks
|
||||
.filter((task) => {
|
||||
if (!task.dueDate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dateKey === todayKey) {
|
||||
return task.dueDate <= todayKey;
|
||||
}
|
||||
|
||||
return task.dueDate === dateKey;
|
||||
})
|
||||
.sort(compareCareTasks);
|
||||
}
|
||||
|
||||
function compareCareTasks(left: CareTask, right: CareTask) {
|
||||
const dueComparison = (left.dueDate ?? '').localeCompare(right.dueDate ?? '');
|
||||
if (dueComparison !== 0) {
|
||||
return dueComparison;
|
||||
}
|
||||
|
||||
const plantComparison = left.plantName.localeCompare(right.plantName);
|
||||
if (plantComparison !== 0) {
|
||||
return plantComparison;
|
||||
}
|
||||
|
||||
return left.action.localeCompare(right.action);
|
||||
}
|
||||
|
||||
function getDateKey(date: Date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ export type CareTask = {
|
||||
careActivityId: number;
|
||||
careActionId: number;
|
||||
action: string;
|
||||
dueDate: string | null;
|
||||
due: string;
|
||||
status: CareStatus;
|
||||
};
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
:root {
|
||||
color: #161616;
|
||||
background: #f4f4f4;
|
||||
color: #24342c;
|
||||
background: #f6f5ef;
|
||||
font-family: 'IBM Plex Sans', Arial, Helvetica, sans-serif;
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
--border: #e0e0e0;
|
||||
--rule: #c6c6c6;
|
||||
--muted: #6f6f6f;
|
||||
--panel: #fff;
|
||||
--side: #f4f4f4;
|
||||
--row: #f4f4f4;
|
||||
--hover: #e8f0fe;
|
||||
--link: #0f62fe;
|
||||
--focus: #0f62fe;
|
||||
--field: #f4f4f4;
|
||||
--layer: #fff;
|
||||
--warning: #8a5a00;
|
||||
--danger: #da1e28;
|
||||
--ok: #198038;
|
||||
--border: #ded8ca;
|
||||
--rule: #cbbfaaaa;
|
||||
--muted: #6d776c;
|
||||
--panel: #fffdf7;
|
||||
--side: #efeee5;
|
||||
--row: #f8f6ee;
|
||||
--hover: #eef4e8;
|
||||
--link: #3d6f4b;
|
||||
--focus: #2f6f7e;
|
||||
--field: #f5f3eb;
|
||||
--layer: #fffdf7;
|
||||
--warning: #9a6508;
|
||||
--danger: #b44336;
|
||||
--ok: #3f7d55;
|
||||
--soil: #7c6144;
|
||||
--sage: #dbe7d2;
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -30,7 +32,9 @@ body {
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
background: #f4f4f4;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(219, 231, 210, 0.55), rgba(246, 245, 239, 0) 260px),
|
||||
#f6f5ef;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@@ -115,12 +119,12 @@ p {
|
||||
grid-template-columns: minmax(190px, 260px) minmax(260px, 680px) minmax(120px, 1fr);
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
min-height: 64px;
|
||||
padding: 10px 22px;
|
||||
border-bottom: 0;
|
||||
background: #161616;
|
||||
color: #f4f4f4;
|
||||
box-shadow: none;
|
||||
min-height: 68px;
|
||||
padding: 12px 24px;
|
||||
border-bottom: 1px solid #274333;
|
||||
background: #1f3528;
|
||||
color: #fffdf7;
|
||||
box-shadow: 0 1px 0 rgba(36, 52, 44, 0.08);
|
||||
}
|
||||
|
||||
.catalog-brand {
|
||||
@@ -129,7 +133,7 @@ p {
|
||||
}
|
||||
|
||||
.catalog-logo {
|
||||
color: #fff;
|
||||
color: #fffdf7;
|
||||
font-size: 1.65rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
@@ -137,7 +141,7 @@ p {
|
||||
|
||||
.catalog-subtitle,
|
||||
.catalog-contact span {
|
||||
color: #c6c6c6;
|
||||
color: #c8d7c3;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -145,7 +149,7 @@ p {
|
||||
.catalog-contact {
|
||||
display: grid;
|
||||
justify-items: end;
|
||||
color: #fff;
|
||||
color: #fffdf7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -163,13 +167,14 @@ p {
|
||||
margin: 0 auto;
|
||||
border-right: 1px solid var(--border);
|
||||
border-left: 1px solid var(--border);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.catalog-sidebar {
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
top: 68px;
|
||||
min-width: 0;
|
||||
min-height: calc(100vh - 64px);
|
||||
min-height: calc(100vh - 68px);
|
||||
padding: 16px 16px 24px 22px;
|
||||
border-right: 1px solid var(--border);
|
||||
background: var(--side);
|
||||
@@ -178,7 +183,7 @@ p {
|
||||
.catalog-sidebar h2,
|
||||
.catalog-help h3 {
|
||||
margin: 0 0 8px;
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
@@ -207,9 +212,10 @@ p {
|
||||
min-width: 0;
|
||||
min-height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: #525252;
|
||||
color: #4f5f54;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
@@ -232,17 +238,19 @@ p {
|
||||
}
|
||||
|
||||
.catalog-nav button:hover {
|
||||
background: #e8e8e8;
|
||||
color: #161616;
|
||||
border-color: #d2c8b7;
|
||||
background: #f7f4ea;
|
||||
color: #24342c;
|
||||
}
|
||||
|
||||
.text-button:hover {
|
||||
color: #0043ce;
|
||||
color: #294f36;
|
||||
}
|
||||
|
||||
.catalog-nav button[aria-current='page'] {
|
||||
background: #e0e0e0;
|
||||
color: #161616;
|
||||
border-color: #c4d5bc;
|
||||
background: var(--sage);
|
||||
color: #24342c;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -252,15 +260,16 @@ p {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 3px;
|
||||
background: var(--link);
|
||||
border-radius: 999px;
|
||||
background: var(--ok);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.catalog-help {
|
||||
margin-top: 22px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #cfcfcf;
|
||||
color: #333;
|
||||
border-top: 1px solid #d2c8b7;
|
||||
color: #4d5a51;
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
@@ -270,8 +279,8 @@ p {
|
||||
|
||||
.catalog-main {
|
||||
min-width: 0;
|
||||
padding: 16px 22px 36px;
|
||||
background: #fff;
|
||||
padding: 18px 22px 40px;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.catalog-page-title {
|
||||
@@ -285,7 +294,8 @@ p {
|
||||
|
||||
.catalog-page-title h1 {
|
||||
margin: 0 0 6px;
|
||||
font-weight: 500;
|
||||
color: #24342c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -310,7 +320,7 @@ p {
|
||||
.plant-row,
|
||||
.task-row {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0;
|
||||
border-radius: 8px;
|
||||
background: var(--panel);
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -320,8 +330,8 @@ p {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
border-top: 0;
|
||||
padding: 12px 14px;
|
||||
border-left: 4px solid var(--link);
|
||||
}
|
||||
|
||||
.summary-panel h2 {
|
||||
@@ -331,7 +341,7 @@ p {
|
||||
|
||||
.summary-panel p {
|
||||
max-width: 68ch;
|
||||
color: #444;
|
||||
color: #59675d;
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
@@ -342,7 +352,8 @@ p {
|
||||
}
|
||||
|
||||
.editor-panel {
|
||||
padding: 10px 12px;
|
||||
padding: 12px;
|
||||
background: #fbfaf4;
|
||||
}
|
||||
|
||||
.section-heading,
|
||||
@@ -364,10 +375,10 @@ p {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: #e0e0e0;
|
||||
color: #161616;
|
||||
border: 1px solid #cfc4b4;
|
||||
border-radius: 6px;
|
||||
background: #f4f0e5;
|
||||
color: #24342c;
|
||||
box-shadow: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -376,7 +387,8 @@ p {
|
||||
min-height: 34px;
|
||||
padding: 0 12px;
|
||||
background: var(--link);
|
||||
color: #fff;
|
||||
border-color: var(--link);
|
||||
color: #fffdf7;
|
||||
}
|
||||
|
||||
.small-action {
|
||||
@@ -402,12 +414,13 @@ p {
|
||||
}
|
||||
|
||||
.primary-action:hover:not(:disabled) {
|
||||
background: #0353e9;
|
||||
background: #315c3d;
|
||||
}
|
||||
|
||||
.small-action:hover:not(:disabled),
|
||||
.icon-button:hover:not(:disabled) {
|
||||
background: #d0d0d0;
|
||||
border-color: #b8aa98;
|
||||
background: #e9e2d4;
|
||||
}
|
||||
|
||||
.plant-mark svg,
|
||||
@@ -419,6 +432,76 @@ p {
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.week-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.week-day {
|
||||
position: relative;
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
min-height: 74px;
|
||||
align-content: space-between;
|
||||
gap: 4px;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
background: #fbfaf4;
|
||||
color: #24342c;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.week-day:hover {
|
||||
border-color: #b8aa98;
|
||||
background: var(--hover);
|
||||
}
|
||||
|
||||
.week-day[aria-selected='true'] {
|
||||
border-color: var(--link);
|
||||
background: var(--sage);
|
||||
box-shadow: inset 0 0 0 1px var(--link);
|
||||
}
|
||||
|
||||
.week-day span:first-child,
|
||||
.week-day small {
|
||||
color: var(--muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.week-day strong {
|
||||
color: #24342c;
|
||||
font-size: 1.35rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.week-day small {
|
||||
display: inline-flex;
|
||||
width: fit-content;
|
||||
min-width: 22px;
|
||||
min-height: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 6px;
|
||||
border-radius: 999px;
|
||||
background: #ece6d9;
|
||||
color: #4f5f54;
|
||||
}
|
||||
|
||||
.week-day-alert {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--danger);
|
||||
}
|
||||
|
||||
.task-list,
|
||||
.plant-list,
|
||||
.plant-grid,
|
||||
@@ -426,7 +509,7 @@ p {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
border-top: 1px solid var(--border);
|
||||
background: #fff;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.task-row,
|
||||
@@ -435,8 +518,9 @@ p {
|
||||
.detail-row {
|
||||
min-height: 42px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #fff;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.task-row:nth-child(even),
|
||||
@@ -462,14 +546,14 @@ p {
|
||||
}
|
||||
|
||||
.task-row-group {
|
||||
background: #f4f4f4;
|
||||
background: #f3efe3;
|
||||
}
|
||||
|
||||
.task-list-label {
|
||||
margin: 0;
|
||||
padding: 7px 8px 5px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #f4f4f4;
|
||||
background: #f3efe3;
|
||||
color: var(--muted);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 500;
|
||||
@@ -510,7 +594,7 @@ p {
|
||||
display: inline;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #444;
|
||||
color: #59675d;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.25;
|
||||
text-overflow: ellipsis;
|
||||
@@ -549,7 +633,7 @@ p {
|
||||
.detail-row p,
|
||||
.taxon,
|
||||
.empty-state {
|
||||
color: #444;
|
||||
color: #59675d;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
@@ -599,13 +683,13 @@ dd {
|
||||
.empty-state {
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #f4f4f4;
|
||||
background: #f8f6ee;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 0;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.status-dot.due {
|
||||
@@ -626,29 +710,29 @@ dd {
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
border: 1px solid currentColor;
|
||||
border-radius: 0;
|
||||
background: #fff;
|
||||
border-radius: 999px;
|
||||
background: var(--panel);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-pill.due {
|
||||
background: #fff1f1;
|
||||
background: #fbe9e4;
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.status-pill.soon {
|
||||
background: #fff8d6;
|
||||
background: #fbefd2;
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
.status-pill.ok {
|
||||
background: #defbe6;
|
||||
background: #e5f1df;
|
||||
color: var(--ok);
|
||||
}
|
||||
|
||||
.status-pill.unscheduled {
|
||||
background: #e0e0e0;
|
||||
background: #ece6d9;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@@ -663,7 +747,7 @@ dd {
|
||||
.flag-assignment-form label {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
color: #525252;
|
||||
color: #4f5f54;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -675,11 +759,10 @@ dd {
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #8d8d8d;
|
||||
border-radius: 0;
|
||||
border: 1px solid #cfc4b4;
|
||||
border-radius: 6px;
|
||||
background: var(--field);
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@@ -699,7 +782,8 @@ dd {
|
||||
align-self: end;
|
||||
padding: 5px 7px;
|
||||
border: 1px solid var(--border);
|
||||
background: #f4f4f4;
|
||||
border-radius: 6px;
|
||||
background: #f8f6ee;
|
||||
}
|
||||
|
||||
.plant-form .toggle-field input,
|
||||
@@ -722,12 +806,13 @@ dd {
|
||||
margin: 0;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--border);
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.resource-picker legend {
|
||||
padding: 0 4px;
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -777,7 +862,7 @@ dd {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #fff;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.activity-resource-header,
|
||||
@@ -850,7 +935,7 @@ dd {
|
||||
|
||||
.schedule-hint {
|
||||
margin: 8px 0 0;
|
||||
color: #444;
|
||||
color: #59675d;
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
@@ -860,7 +945,8 @@ dd {
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
border-left: 3px solid var(--link);
|
||||
background: #f4f4f4;
|
||||
border-radius: 0 6px 6px 0;
|
||||
background: #f3efe3;
|
||||
}
|
||||
|
||||
.schedule-preview span {
|
||||
@@ -871,7 +957,7 @@ dd {
|
||||
}
|
||||
|
||||
.schedule-preview strong {
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -890,7 +976,8 @@ dd {
|
||||
margin: 10px 0 0;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.schedule-options legend,
|
||||
@@ -919,8 +1006,8 @@ dd {
|
||||
.schedule-end-options input[type='number'] {
|
||||
min-height: 34px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #8d8d8d;
|
||||
border: 1px solid #cfc4b4;
|
||||
border-radius: 6px;
|
||||
background: var(--field);
|
||||
}
|
||||
|
||||
@@ -930,8 +1017,9 @@ dd {
|
||||
height: 28px;
|
||||
place-items: center;
|
||||
border: 1px solid var(--border);
|
||||
background: #f4f4f4;
|
||||
color: #161616;
|
||||
border-radius: 6px;
|
||||
background: #f8f6ee;
|
||||
color: #24342c;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
@@ -942,7 +1030,7 @@ dd {
|
||||
|
||||
.weekday-options label:has(input:checked) {
|
||||
border-color: var(--link);
|
||||
background: #e8f0ff;
|
||||
background: var(--sage);
|
||||
color: var(--link);
|
||||
}
|
||||
|
||||
@@ -959,11 +1047,10 @@ dd {
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #8d8d8d;
|
||||
border-radius: 0;
|
||||
border: 1px solid #cfc4b4;
|
||||
border-radius: 6px;
|
||||
background: var(--field);
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
}
|
||||
|
||||
.compact-plant-list {
|
||||
@@ -1019,7 +1106,7 @@ dd {
|
||||
}
|
||||
|
||||
.plant-detail-meta strong {
|
||||
color: #161616;
|
||||
color: #24342c;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
@@ -1090,7 +1177,8 @@ dd {
|
||||
align-items: center;
|
||||
padding: 0 7px;
|
||||
border: 1px solid #999;
|
||||
color: #161616;
|
||||
border-radius: 999px;
|
||||
color: #24342c;
|
||||
font-size: 0.74rem;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
@@ -1100,7 +1188,8 @@ dd {
|
||||
margin-top: 8px;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #f4f4f4;
|
||||
border-radius: 8px;
|
||||
background: #f8f6ee;
|
||||
}
|
||||
|
||||
.flag-assignment-form label {
|
||||
@@ -1199,6 +1288,17 @@ dd {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.week-strip {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.week-day {
|
||||
flex: 0 0 78px;
|
||||
}
|
||||
|
||||
.catalog-page-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -350,6 +350,7 @@ namespace plant_manager
|
||||
int CareActivityId,
|
||||
int CareActionId,
|
||||
string Action,
|
||||
string? DueDate,
|
||||
string Due,
|
||||
string Status)
|
||||
{
|
||||
@@ -368,6 +369,7 @@ namespace plant_manager
|
||||
schedule.CareActivityId,
|
||||
schedule.CareActionId,
|
||||
schedule.CareActivity.Name,
|
||||
nextCare?.ToString("yyyy-MM-dd"),
|
||||
PlantCareFormatter.FormatRelativeDate(nextCare, today, "Unscheduled"),
|
||||
PlantCareFormatter.GetStatus(nextCare, today));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user