Skip to content

Commit 12e7697

Browse files
coderabbit
1 parent 75e3d2b commit 12e7697

File tree

5 files changed

+80
-45
lines changed

5 files changed

+80
-45
lines changed

apps/desktop/src/components/main/body/calendars.tsx

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
subDays,
1616
} from "@hypr/utils";
1717

18-
import { CalendarDaysIcon, CalendarIcon, ChevronLeftIcon, ChevronRightIcon, FileTextIcon, Pen } from "lucide-react";
18+
import { Calendar, CalendarDays, ChevronLeft, ChevronRight, FileText, Pen } from "lucide-react";
1919
import { useState } from "react";
2020

2121
import * as persisted from "../../../store/tinybase/persisted";
@@ -34,7 +34,7 @@ export const TabItemCalendar: TabItem = (
3434
) => {
3535
return (
3636
<TabItemBase
37-
icon={<CalendarIcon className="w-4 h-4" />}
37+
icon={<Calendar size={16} />}
3838
title={"Calendar"}
3939
active={tab.active}
4040
handleCloseThis={() => handleCloseThis(tab)}
@@ -54,14 +54,8 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
5454

5555
const { openCurrent } = useTabs();
5656

57-
// Fetch all calendars
5857
const calendarIds = persisted.UI.useRowIds("calendars", persisted.STORE_ID);
59-
const calendars = calendarIds.map((id) => ({
60-
id,
61-
...persisted.UI.useRow("calendars", id, persisted.STORE_ID),
62-
}));
6358

64-
// Initialize selectedCalendars with all calendar IDs by default
6559
const [selectedCalendars, setSelectedCalendars] = useState<Set<string>>(() => new Set(calendarIds));
6660

6761
const toggleCalendar = (calendarId: string) => {
@@ -105,26 +99,19 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
10599
<aside className="w-64 border-r border-neutral-200 bg-white flex flex-col">
106100
<div className="p-2 border-b border-neutral-200 flex items-center gap-2">
107101
<Button size="icon" variant={sidebarOpen ? "default" : "ghost"} onClick={() => setSidebarOpen(false)}>
108-
<CalendarDaysIcon size={16} />
102+
<CalendarDays size={16} />
109103
</Button>
110104
My Calendars
111105
</div>
112106
<div className="flex-1 overflow-y-auto p-4">
113107
<div className="space-y-3">
114-
{calendars.map((calendar) => (
115-
<div key={calendar.id} className="flex items-center space-x-2">
116-
<Checkbox
117-
id={`calendar-${calendar.id}`}
118-
checked={selectedCalendars.has(calendar.id)}
119-
onCheckedChange={() => toggleCalendar(calendar.id)}
120-
/>
121-
<label
122-
htmlFor={`calendar-${calendar.id}`}
123-
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
124-
>
125-
{calendar.name}
126-
</label>
127-
</div>
108+
{calendarIds.map((id) => (
109+
<CalendarCheckboxRow
110+
key={id}
111+
id={id}
112+
checked={selectedCalendars.has(id)}
113+
onToggle={() => toggleCalendar(id)}
114+
/>
128115
))}
129116
</div>
130117
</div>
@@ -136,7 +123,7 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
136123
<div className="p-2 flex items-center relative">
137124
{!sidebarOpen && (
138125
<Button size="icon" variant="ghost" onClick={() => setSidebarOpen(true)}>
139-
<CalendarDaysIcon size={16} />
126+
<CalendarDays size={16} />
140127
</Button>
141128
)}
142129
<div className="text-xl font-semibold absolute left-1/2 transform -translate-x-1/2">{monthLabel}</div>
@@ -146,7 +133,7 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
146133
size="icon"
147134
onClick={handlePreviousMonth}
148135
>
149-
<ChevronLeftIcon size={16} />
136+
<ChevronLeft size={16} />
150137
</Button>
151138

152139
<Button
@@ -162,7 +149,7 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
162149
size="icon"
163150
onClick={handleNextMonth}
164151
>
165-
<ChevronRightIcon size={16} />
152+
<ChevronRight size={16} />
166153
</Button>
167154
</ButtonGroup>
168155
</div>
@@ -202,6 +189,23 @@ export function TabContentCalendar({ tab }: { tab: Tab }) {
202189
);
203190
}
204191

192+
function CalendarCheckboxRow(
193+
{ id, checked, onToggle }: { id: string; checked: boolean; onToggle: () => void },
194+
) {
195+
const calendar = persisted.UI.useRow("calendars", id, persisted.STORE_ID);
196+
return (
197+
<div className="flex items-center space-x-2">
198+
<Checkbox id={`calendar-${id}`} checked={checked} onCheckedChange={onToggle} />
199+
<label
200+
htmlFor={`calendar-${id}`}
201+
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
202+
>
203+
{calendar?.name ?? "Untitled"}
204+
</label>
205+
</div>
206+
);
207+
}
208+
205209
function TabContentCalendarDay({
206210
day,
207211
isCurrentMonth,
@@ -222,10 +226,11 @@ function TabContentCalendarDay({
222226
persisted.STORE_ID,
223227
);
224228

225-
// Filter events by selected calendars
229+
const store = persisted.UI.useStore(persisted.STORE_ID);
230+
226231
const eventIds = allEventIds.filter((eventId) => {
227-
const event = persisted.UI.useRow("events", eventId, persisted.STORE_ID);
228-
return event.calendar_id && selectedCalendars.has(event.calendar_id);
232+
const event = store?.getRow("events", eventId);
233+
return event?.calendar_id && selectedCalendars.has(event.calendar_id as string);
229234
});
230235

231236
const sessionIds = persisted.UI.useSliceRowIds(
@@ -346,6 +351,10 @@ function TabContentCalendarDayEvents({ eventId }: { eventId: string }) {
346351
const start = new Date(event.started_at);
347352
const end = new Date(event.ended_at);
348353

354+
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
355+
return "";
356+
}
357+
349358
if (isSameDay(start, end)) {
350359
return `${format(start, "MMM d")}, ${format(start, "h:mm a")} - ${format(end, "h:mm a")}`;
351360
}
@@ -356,7 +365,7 @@ function TabContentCalendarDayEvents({ eventId }: { eventId: string }) {
356365
<Popover open={open} onOpenChange={setOpen}>
357366
<PopoverTrigger asChild>
358367
<div className="flex items-center space-x-1 px-0.5 py-0.5 cursor-pointer rounded hover:bg-neutral-200 transition-colors h-5">
359-
<CalendarIcon className="w-2.5 h-2.5 text-neutral-500 flex-shrink-0" />
368+
<Calendar size={12} className="text-neutral-500 flex-shrink-0" />
360369
<div className="flex-1 text-xs text-neutral-800 truncate">
361370
{event.title}
362371
</div>
@@ -377,7 +386,7 @@ function TabContentCalendarDayEvents({ eventId }: { eventId: string }) {
377386
className="flex items-center gap-2 px-2 py-1 bg-neutral-50 border border-neutral-200 rounded-md cursor-pointer hover:bg-neutral-100 transition-colors"
378387
onClick={handleClick}
379388
>
380-
<FileTextIcon className="size-3 text-neutral-600 flex-shrink-0" />
389+
<FileText size={12} className="text-neutral-600 flex-shrink-0" />
381390
<div className="text-xs font-medium text-neutral-800 truncate">
382391
{linkedSession?.title || "Untitled Note"}
383392
</div>
@@ -412,15 +421,21 @@ function TabContentCalendarDaySessions({ sessionId }: { sessionId: string }) {
412421
};
413422

414423
const formatSessionTime = () => {
415-
const created = new Date(session.created_at || "");
424+
if (!session.created_at) {
425+
return "Created: —";
426+
}
427+
const created = new Date(session.created_at);
428+
if (isNaN(created.getTime())) {
429+
return "Created: —";
430+
}
416431
return `Created: ${format(created, "MMM d, h:mm a")}`;
417432
};
418433

419434
return (
420435
<Popover open={open} onOpenChange={setOpen}>
421436
<PopoverTrigger asChild>
422437
<div className="flex items-center space-x-1 px-0.5 py-0.5 cursor-pointer rounded hover:bg-neutral-200 transition-colors h-5">
423-
<FileTextIcon className="w-2.5 h-2.5 text-neutral-500 flex-shrink-0" />
438+
<FileText size={12} className="text-neutral-500 flex-shrink-0" />
424439
<div className="flex-1 text-xs text-neutral-800 truncate">
425440
{event && session.event_id ? event.title : session.title || "Untitled"}
426441
</div>
@@ -439,7 +454,7 @@ function TabContentCalendarDaySessions({ sessionId }: { sessionId: string }) {
439454
className="flex items-center gap-2 px-2 py-1 bg-neutral-50 border border-neutral-200 rounded-md cursor-pointer hover:bg-neutral-100 transition-colors"
440455
onClick={handleClick}
441456
>
442-
<FileTextIcon className="size-3 text-neutral-600 flex-shrink-0" />
457+
<FileText size={12} className="text-neutral-600 flex-shrink-0" />
443458
<div className="text-xs font-medium text-neutral-800 truncate">
444459
{event && session.event_id ? event.title : session.title || "Untitled"}
445460
</div>

apps/desktop/src/components/main/body/contacts/organizations.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export function OrganizationsColumn({
2828

2929
return organizationIds.filter((id) => {
3030
const org = allOrgs[id];
31-
return org?.name?.toLowerCase().includes(searchValue.toLowerCase());
31+
const nameLower = (org?.name ?? "").toLowerCase();
32+
return nameLower.includes(searchValue.toLowerCase());
3233
});
3334
}, [organizationIds, searchValue, allOrgs]);
3435

@@ -86,6 +87,14 @@ function useSortedOrganizationIds() {
8687
undefined,
8788
persisted.STORE_ID,
8889
);
90+
const reverseAlphabeticalIds = persisted.UI.useResultSortedRowIds(
91+
persisted.QUERIES.visibleOrganizations,
92+
"name",
93+
true,
94+
0,
95+
undefined,
96+
persisted.STORE_ID,
97+
);
8998
const newestIds = persisted.UI.useResultSortedRowIds(
9099
persisted.QUERIES.visibleOrganizations,
91100
"created_at",
@@ -105,6 +114,8 @@ function useSortedOrganizationIds() {
105114

106115
const organizationIds = sortOption === "alphabetical"
107116
? alphabeticalIds
117+
: sortOption === "reverse-alphabetical"
118+
? reverseAlphabeticalIds
108119
: sortOption === "newest"
109120
? newestIds
110121
: oldestIds;

apps/desktop/src/components/main/body/contacts/people.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@ export function PeopleColumn({
2626

2727
return humanIds.filter((id) => {
2828
const human = allHumans[id];
29-
const searchLower = searchValue.toLowerCase();
30-
return (
31-
human?.name?.toLowerCase().includes(searchLower)
32-
|| human?.email?.toLowerCase().includes(searchLower)
33-
);
29+
const q = searchValue.toLowerCase();
30+
const name = (human?.name ?? "").toLowerCase();
31+
const email = (human?.email ?? "").toLowerCase();
32+
return name.includes(q) || email.includes(q);
3433
});
3534
}, [humanIds, searchValue, allHumans]);
3635

@@ -71,6 +70,14 @@ export function useSortedHumanIds(currentOrgId?: string | null) {
7170
undefined,
7271
persisted.STORE_ID,
7372
);
73+
const allReverseAlphabeticalIds = persisted.UI.useResultSortedRowIds(
74+
persisted.QUERIES.visibleHumans,
75+
"name",
76+
true,
77+
0,
78+
undefined,
79+
persisted.STORE_ID,
80+
);
7481
const allNewestIds = persisted.UI.useResultSortedRowIds(
7582
persisted.QUERIES.visibleHumans,
7683
"created_at",
@@ -97,11 +104,15 @@ export function useSortedHumanIds(currentOrgId?: string | null) {
97104
const humanIds = currentOrgId
98105
? (sortOption === "alphabetical"
99106
? allAlphabeticalIds
107+
: sortOption === "reverse-alphabetical"
108+
? allReverseAlphabeticalIds
100109
: sortOption === "newest"
101110
? allNewestIds
102111
: allOldestIds).filter((id) => thisOrgHumanIds.includes(id))
103112
: (sortOption === "alphabetical"
104113
? allAlphabeticalIds
114+
: sortOption === "reverse-alphabetical"
115+
? allReverseAlphabeticalIds
105116
: sortOption === "newest"
106117
? allNewestIds
107118
: allOldestIds);

apps/desktop/src/components/main/body/contacts/shared.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ export function SortDropdown({
3030
value={sortOption}
3131
onValueChange={(value: SortOption) => setSortOption(value)}
3232
>
33-
<SelectTrigger>
34-
<Button variant="ghost" size="icon">
35-
<ArrowDownUp size={16} />
36-
</Button>
33+
<SelectTrigger className="h-8 w-8 p-0" aria-label="Sort options">
34+
<ArrowDownUp size={16} />
3735
</SelectTrigger>
3836
<SelectContent>
3937
<SelectItem value="alphabetical" className="text-xs">

apps/desktop/src/components/main/sidebar/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function LeftSidebar() {
3333
</Button>
3434
</header>
3535

36-
<div className="flex flex-col flex-1 overflow-hidden gap-1 relative">
36+
<div className="flex flex-col flex-1 overflow-hidden gap-1">
3737
<div className="flex-1 min-h-0 overflow-hidden">
3838
{showSearchResults ? <SearchResults /> : <TimelineView />}
3939
</div>

0 commit comments

Comments
 (0)