Skip to content

Commit dc1201f

Browse files
feat(calendar-selector): Improve calendar source sorting (#818)
1 parent d3e3eea commit dc1201f

File tree

1 file changed

+91
-21
lines changed

1 file changed

+91
-21
lines changed

apps/desktop/src/components/settings/components/calendar/calendar-selector.tsx

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@ export function CalendarSelector() {
1616
queryFn: async () => {
1717
const calendars = await dbCommands.listCalendars(userId);
1818
const grouped = calendars.reduce((acc, calendar) => {
19-
acc[calendar.source || "Other"] = acc[calendar.source || "Other"] || [];
20-
acc[calendar.source || "Other"].push(calendar);
19+
let source = calendar.source || "Other";
20+
21+
if (!source.includes("@")) {
22+
source = "Other";
23+
}
24+
25+
acc[source] = acc[source] || [];
26+
acc[source].push(calendar);
2127
return acc;
2228
}, {} as Record<string, Calendar[]>);
2329

@@ -101,29 +107,93 @@ export function CalendarSelector() {
101107
</div>
102108
)
103109
: (
104-
Object.entries(calendarsQuery.data?.grouped ?? {}).map(([source, sourceCalendars]) => (
110+
Object.entries(calendarsQuery.data?.grouped ?? {}).sort(([sourceA], [sourceB]) => {
111+
const isWorkEmail = (email: string) => {
112+
if (!email.includes("@")) {
113+
return false;
114+
}
115+
116+
const domain = email.split("@")[1]?.toLowerCase();
117+
118+
const personalDomains = [
119+
"gmail.com",
120+
"yahoo.com",
121+
"hotmail.com",
122+
"outlook.com",
123+
"icloud.com",
124+
"aol.com",
125+
"protonmail.com",
126+
"mail.com",
127+
];
128+
129+
return domain && !personalDomains.includes(domain);
130+
};
131+
132+
const isWorkEmailA = isWorkEmail(sourceA);
133+
const isWorkEmailB = isWorkEmail(sourceB);
134+
135+
if (isWorkEmailA && !isWorkEmailB) {
136+
return -1;
137+
}
138+
if (!isWorkEmailA && isWorkEmailB) {
139+
return 1;
140+
}
141+
142+
if (sourceA.includes("@") && !sourceB.includes("@")) {
143+
return -1;
144+
}
145+
if (!sourceA.includes("@") && sourceB.includes("@")) {
146+
return 1;
147+
}
148+
149+
if (sourceA === "Other" && sourceB !== "Other") {
150+
return 1;
151+
}
152+
if (sourceA !== "Other" && sourceB === "Other") {
153+
return -1;
154+
}
155+
156+
return sourceA.localeCompare(sourceB);
157+
}).map(([source, sourceCalendars]) => (
105158
<div key={source} className="mb-5">
106159
<div className="text-sm font-semibold text-gray-800 mb-2">{source}</div>
107160
<div className="pl-2 space-y-2.5">
108-
{sourceCalendars.map((calendar) => (
109-
<div
110-
key={calendar.id}
111-
className="flex items-center space-x-3 py-1 px-2 rounded-md hover:bg-gray-50 transition-colors"
112-
>
113-
<Checkbox
114-
id={`calendar-${calendar.id}`}
115-
checked={calendar.selected}
116-
onCheckedChange={() => toggleCalendarSelectedMutation.mutate(calendar)}
117-
className="h-4 w-4"
118-
/>
119-
<label
120-
htmlFor={`calendar-${calendar.id}`}
121-
className="text-sm font-medium cursor-pointer text-gray-700 flex-1"
161+
{sourceCalendars
162+
.sort((a, b) => {
163+
// Check if calendar names contain email addresses
164+
const aHasEmail = a.name.includes("@");
165+
const bHasEmail = b.name.includes("@");
166+
167+
// Email-based calendars first
168+
if (aHasEmail && !bHasEmail) {
169+
return -1;
170+
}
171+
if (!aHasEmail && bHasEmail) {
172+
return 1;
173+
}
174+
175+
// Then alphabetical order
176+
return a.name.localeCompare(b.name);
177+
})
178+
.map((calendar) => (
179+
<div
180+
key={calendar.id}
181+
className="flex items-center space-x-3 py-1 px-2 rounded-md hover:bg-gray-50 transition-colors"
122182
>
123-
{calendar.name}
124-
</label>
125-
</div>
126-
))}
183+
<Checkbox
184+
id={`calendar-${calendar.id}`}
185+
checked={calendar.selected}
186+
onCheckedChange={() => toggleCalendarSelectedMutation.mutate(calendar)}
187+
className="h-4 w-4"
188+
/>
189+
<label
190+
htmlFor={`calendar-${calendar.id}`}
191+
className="text-sm font-medium cursor-pointer text-gray-700 flex-1"
192+
>
193+
{calendar.name}
194+
</label>
195+
</div>
196+
))}
127197
</div>
128198
</div>
129199
))

0 commit comments

Comments
 (0)