Skip to content

Commit bb7b3ad

Browse files
committed
sharper corners
1 parent a53501a commit bb7b3ad

7 files changed

Lines changed: 63 additions & 47 deletions

File tree

STYLEGUIDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@
100100
- `TrendingUp` - Summary/analytics view
101101
- `Plus` - Add new entry action
102102
- `Download` - Export functionality
103-
- `Share2` - Share/send functionality
104103

105104
## Design Principles
106105

src/components/AddEntryDialog.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,18 @@ export function AddEntryDialog({ onAddEntry, buttonClassName }: AddEntryDialogPr
4343

4444
if (!title || !description || !date || !time) return;
4545

46+
// Format time to AM/PM
47+
const [hours, minutes] = time.split(":");
48+
const hoursNum = parseInt(hours, 10);
49+
const ampm = hoursNum >= 12 ? "PM" : "AM";
50+
const formattedHours = hoursNum % 12 || 12; // Convert 0 to 12 for 12 AM
51+
const formattedTime = `${String(formattedHours).padStart(2, '0')}:${minutes} ${ampm}`;
52+
4653
onAddEntry({
4754
type,
4855
title,
4956
description,
50-
time,
57+
time: formattedTime,
5158
status: "upcoming",
5259
provider: provider || undefined,
5360
date: date,

src/components/ChatbotWidget.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function ChatbotWidget() {
5454
<div className="fixed bottom-6 right-6 z-50">
5555
{isOpen && (
5656
<div className="mb-4 w-80 rounded-lg border bg-card shadow-lg">
57-
<div className="flex items-center justify-between border-b bg-medical-blue p-4">
57+
<div className="flex items-center justify-between rounded-t-lg border-b bg-slate-900 p-4">
5858
<h3 className="font-semibold text-white">AI Assistant</h3>
5959
<Button size="icon" variant="ghost" onClick={() => setIsOpen(false)} className="text-white">
6060
<X className="h-4 w-4" />
@@ -102,7 +102,7 @@ export function ChatbotWidget() {
102102
<Button
103103
onClick={() => setIsOpen(!isOpen)}
104104
size="icon"
105-
className={cn("h-14 w-14 rounded-full shadow-lg transition-all", isOpen && "rotate-0")}
105+
className={cn("h-14 w-14 rounded-full shadow-lg transition-all bg-slate-900 hover:bg-slate-800", isOpen && "rotate-0")}
106106
>
107107
{isOpen ? <X className="h-6 w-6" /> : <MessageCircle className="h-6 w-6" />}
108108
</Button>

src/components/SummaryCard.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Card } from "@/components/ui/card";
22
import { Button } from "@/components/ui/button";
33
import { Badge } from "@/components/ui/badge";
4-
import { FileText, Download, Share2 } from "lucide-react";
4+
import { FileText, Download } from "lucide-react";
55
import { TimelineEntryData } from "./TimelineEntry";
66
import { toast } from "sonner";
77

@@ -21,10 +21,6 @@ export function SummaryCard({ entries }: SummaryCardProps) {
2121
toast.success("Summary exported successfully");
2222
};
2323

24-
const handleShare = () => {
25-
toast.success("Sharing link copied to clipboard");
26-
};
27-
2824
return (
2925
<Card className="p-6 space-y-6">
3026
<div className="flex items-start justify-between">

src/components/TimelineEntry.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
Pill, Calendar, FlaskConical, CheckCircle2, XCircle, Clock, LucideIcon,
2+
Pill, Calendar, FlaskConical, CheckCircle2, XCircle, Clock, LucideIcon, Trash2,
33
} from "lucide-react";
44
import { cn } from "@/lib/utils";
55

@@ -19,6 +19,7 @@ export interface TimelineEntryData {
1919
interface TimelineEntryProps {
2020
entry: TimelineEntryData;
2121
onStatusChange: (id: string, newStatus: EntryStatus) => void;
22+
onRemove: (id: string) => void;
2223
isLast?: boolean;
2324
}
2425

@@ -52,7 +53,7 @@ const getStatusToggle = (type: TimelineEntryData["type"], status: EntryStatus):
5253
return { label: "", next: status };
5354
};
5455

55-
export const TimelineEntry = ({ entry, onStatusChange, isLast }: TimelineEntryProps) => {
56+
export const TimelineEntry = ({ entry, onStatusChange, onRemove, isLast }: TimelineEntryProps) => {
5657
const isToggleable = entry.type === "medication" || entry.type === "appointment";
5758
const config = typeConfig[entry.type];
5859
const StatusIcon = statusIcons[entry.status];
@@ -71,32 +72,38 @@ export const TimelineEntry = ({ entry, onStatusChange, isLast }: TimelineEntryPr
7172

7273
{/* left rail icon */}
7374
<div className="relative flex flex-col items-center">
74-
<div className="relative flex h-14 w-14 items-center justify-center rounded-full bg-white shadow-lg ring-1 ring-white/60">
75-
<div className={cn("flex h-11 w-11 items-center justify-center rounded-full border bg-gradient-to-br", config.indicator)}>
75+
<div className="relative flex h-14 w-14 items-center justify-center rounded-2xl bg-white shadow-lg ring-1 ring-white/60">
76+
<div className={cn("flex h-11 w-11 items-center justify-center rounded-xl border bg-gradient-to-br", config.indicator)}>
7677
<config.icon className={cn("h-5 w-5", config.accent)} />
7778
</div>
7879
</div>
7980
</div>
8081

8182
{/* card */}
8283
<div className="flex-1">
83-
<div className="rounded-3xl border border-white/60 bg-white/90 p-6 shadow-[0_14px_36px_rgba(15,23,42,0.08)]">
84+
<div className="rounded-2xl border border-white/60 bg-white/90 p-6 shadow-[0_14px_36px_rgba(15,23,42,0.08)]">
8485
{/* top row — small time + status chip; action at far right */}
8586
<div className="flex items-center gap-3">
8687
<span className="text-sm font-medium text-slate-500">{entry.time}</span>
87-
<span className={cn("inline-flex items-center gap-1 rounded-full px-3 py-1 text-xs font-semibold", statusMeta.chip)}>
88+
<span className={cn("inline-flex items-center gap-1 rounded-md px-3 py-1 text-xs font-semibold", statusMeta.chip)}>
8889
<StatusIcon className="h-3.5 w-3.5" />
8990
{statusMeta.label}
9091
</span>
91-
{isToggleable && statusToggle.label && (
92-
<button
93-
type="button"
94-
onClick={() => onStatusChange(entry.id, statusToggle.next)}
95-
className="ml-auto text-xs font-semibold text-slate-500 hover:text-slate-900"
96-
>
97-
{statusToggle.label}
92+
<div className="ml-auto flex items-center gap-4">
93+
{isToggleable && statusToggle.label && (
94+
<button
95+
type="button"
96+
onClick={() => onStatusChange(entry.id, statusToggle.next)}
97+
className="text-xs font-semibold text-slate-500 hover:text-slate-900"
98+
>
99+
{statusToggle.label}
100+
</button>
101+
)}
102+
<button type="button" onClick={() => onRemove(entry.id)} className="text-slate-400 hover:text-red-500">
103+
<Trash2 className="h-4 w-4" />
104+
<span className="sr-only">Remove entry</span>
98105
</button>
99-
)}
106+
</div>
100107
</div>
101108

102109
{/* title + description */}

src/pages/Index.tsx

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const Index = () => {
2020
const addEntry = useEntriesStore((s) => s.addEntry);
2121
const bulkAdd = useEntriesStore((s) => s.bulkAdd);
2222
const setStatus = useEntriesStore((s) => s.setStatus);
23+
const removeEntry = useEntriesStore((s) => s.removeEntry);
2324

2425
// Seed demo data once if store is empty
2526
useEffect(() => {
@@ -75,6 +76,10 @@ const Index = () => {
7576
setStatus(id, status);
7677
};
7778

79+
const handleRemoveEntry = (id: string) => {
80+
removeEntry(id);
81+
};
82+
7883
const selectedDateStr = useMemo(() => format(selectedDate, "yyyy-MM-dd"), [selectedDate]);
7984

8085
const filteredEntries = useMemo(() => {
@@ -118,38 +123,39 @@ const Index = () => {
118123
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
119124
<div className="space-y-1">
120125
<span className="text-sm font-semibold tracking-tight text-slate-700">Lifeline-</span>
121-
<h1 className="font-semibold text-[40px] leading-[1.05] text-[#0F1729] sm:text-[56px]">
126+
<h1 className="font-semibold text-[44px] leading-[1.05] text-[#0F1729] sm:text-[64px]">
122127
Welcome Back
123128
</h1>
124129
<p className="text-[15px] text-slate-600">
125130
See what’s happening across your health: daily updates to your complete health picture.
126131
</p>
127132
</div>
133+
</div>
128134

135+
<div className="flex items-center justify-between">
136+
{/* Segmented tabs (compact) */}
137+
<TabsList className="mt-1 inline-flex rounded-lg bg-white/70 p-1 ring-1 ring-black/5 shadow-sm backdrop-blur">
138+
{tabConfig.map(({ value, label, Icon }) => (
139+
<TabsTrigger
140+
key={value}
141+
value={value}
142+
className="flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium text-slate-600 transition
143+
data-[state=active]:bg-white data-[state=active]:text-slate-900 data-[state=active]:shadow"
144+
>
145+
<Icon className="h-4 w-4" />
146+
{label}
147+
</TabsTrigger>
148+
))}
149+
</TabsList>
129150
<AddEntryDialog
130151
onAddEntry={handleAddEntry}
131-
buttonClassName="rounded-full bg-slate-900 px-6 py-3 text-base font-semibold text-white shadow-xl transition hover:bg-slate-900/90"
152+
buttonClassName="rounded-lg bg-slate-900 px-5 py-2.5 text-sm font-semibold text-white shadow-lg transition hover:bg-slate-900/90"
132153
/>
133154
</div>
134155

135-
{/* Segmented tabs (compact) */}
136-
<TabsList className="mt-1 inline-flex rounded-full bg-white/70 p-1 ring-1 ring-black/5 shadow-sm backdrop-blur">
137-
{tabConfig.map(({ value, label, Icon }) => (
138-
<TabsTrigger
139-
key={value}
140-
value={value}
141-
className="flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-slate-600 transition
142-
data-[state=active]:bg-white data-[state=active]:text-slate-900 data-[state=active]:shadow"
143-
>
144-
<Icon className="h-4 w-4" />
145-
{label}
146-
</TabsTrigger>
147-
))}
148-
</TabsList>
149-
150156
<TabsContent value="timeline">
151157
<section
152-
className="rounded-[28px] border border-white/55
158+
className="rounded-2xl border border-white/55
153159
bg-[linear-gradient(135deg,hsl(216_100%_97%/.92),hsl(274_100%_96%/.92))]
154160
p-8 shadow-[0_30px_70px_rgba(88,80,236,0.22)] backdrop-blur"
155161
>
@@ -160,14 +166,14 @@ const Index = () => {
160166

161167
<div className="mt-10 space-y-10">
162168
{filteredEntries.length === 0 ? (
163-
<div className="rounded-[24px] border border-white/60 bg-white/90 p-6 shadow-[0_14px_36px_rgba(15,23,42,0.08)]"> <p className="text-lg font-semibold text-slate-700">No entries yet</p>
169+
<div className="rounded-xl border border-white/60 bg-white/90 p-6 shadow-[0_14px_36px_rgba(15,23,42,0.08)]"> <p className="text-lg font-semibold text-slate-700">No entries yet</p>
164170
<p className="mt-2 text-sm text-slate-500">
165171
Start tracking medications, labs, or appointments to fill your day.
166172
</p>
167173
<div className="mt-6 flex justify-center">
168174
<AddEntryDialog
169175
onAddEntry={handleAddEntry}
170-
buttonClassName="rounded-full bg-slate-900/90 px-5 py-2 text-sm font-semibold text-white shadow hover:bg-slate-900"
176+
buttonClassName="rounded-lg bg-slate-900/90 px-5 py-2 text-sm font-semibold text-white shadow hover:bg-slate-900"
171177
/>
172178
</div>
173179
</div>
@@ -178,6 +184,7 @@ const Index = () => {
178184
entry={entry}
179185
isLast={index === filteredEntries.length - 1}
180186
onStatusChange={handleStatusChange}
187+
onRemove={handleRemoveEntry}
181188
/>
182189
))
183190
)}
@@ -186,12 +193,12 @@ const Index = () => {
186193
</TabsContent>
187194

188195
<TabsContent value="summary">
189-
<section className="rounded-[24px] border border-white/60 bg-white/80 p-6 shadow-[0_25px_60px_rgba(15,23,42,0.08)] backdrop-blur"> <SummaryCard entries={entries} />
196+
<section className="rounded-xl border border-white/60 bg-white/80 p-6 shadow-[0_25px_60px_rgba(15,23,42,0.08)] backdrop-blur"> <SummaryCard entries={entries} />
190197
</section>
191198
</TabsContent>
192199

193200
<TabsContent value="calendar">
194-
<section className="rounded-[24px] border border-white/60 bg-white/80 p-6 shadow-[0_25px_60px_rgba(15,23,42,0.08)] backdrop-blur"> <div className="mb-6 space-y-1">
201+
<section className="rounded-xl border border-white/60 bg-white/80 p-6 shadow-[0_25px_60px_rgba(15,23,42,0.08)] backdrop-blur"> <div className="mb-6 space-y-1">
195202
<h2 className="text-2xl font-semibold text-slate-900">Select a Date</h2>
196203
<p className="text-sm text-slate-600">Choose a date to view its detailed timeline.</p>
197204
</div>
@@ -200,7 +207,7 @@ const Index = () => {
200207
mode="single"
201208
selected={selectedDate}
202209
onSelect={(date) => date && setSelectedDate(date)}
203-
className="rounded-2xl border border-white/70 bg-white"
210+
className="rounded-xl border border-white/70 bg-white"
204211
/>
205212
</div>
206213
</section>

src/store/entries.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ type EntriesState = {
66
entries: TimelineEntryData[];
77
addEntry: (e: Omit<TimelineEntryData, "id">) => string;
88
bulkAdd: (arr: Omit<TimelineEntryData, "id">[]) => void;
9-
setStatus: (id: string, status: EntryStatus) => void;
109
removeEntry: (id: string) => void;
10+
setStatus: (id: string, status: EntryStatus) => void;
1111
clearAll: () => void;
1212
};
1313

0 commit comments

Comments
 (0)