Spaces:
Running
Running
gpt-engineer-app[bot]
commited on
Commit
·
a390f29
1
Parent(s):
19bc1d2
Set default calendar view and add filters
Browse filesThe calendar view is now yearly by default, and a filter bar has been added to filter by conference categories.
- src/components/FilterBar.tsx +1 -0
- src/pages/Calendar.tsx +11 -4
src/components/FilterBar.tsx
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import { useMemo } from "react";
|
2 |
import conferencesData from "@/data/conferences.yml";
|
3 |
|
|
|
1 |
+
|
2 |
import { useMemo } from "react";
|
3 |
import conferencesData from "@/data/conferences.yml";
|
4 |
|
src/pages/Calendar.tsx
CHANGED
@@ -6,6 +6,7 @@ import { Calendar } from "@/components/ui/calendar";
|
|
6 |
import { parseISO, format, isValid, isSameMonth, isSameYear, isSameDay } from "date-fns";
|
7 |
import { Toggle } from "@/components/ui/toggle";
|
8 |
import Header from "@/components/Header";
|
|
|
9 |
import {
|
10 |
Dialog,
|
11 |
DialogContent,
|
@@ -21,8 +22,9 @@ import {
|
|
21 |
|
22 |
const CalendarPage = () => {
|
23 |
const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
|
24 |
-
const [isYearView, setIsYearView] = useState(
|
25 |
const [searchQuery, setSearchQuery] = useState("");
|
|
|
26 |
const [selectedDayEvents, setSelectedDayEvents] = useState<{ date: Date | null, events: { deadlines: Conference[], conferences: Conference[] } }>({
|
27 |
date: null,
|
28 |
events: { deadlines: [], conferences: [] }
|
@@ -59,7 +61,9 @@ const CalendarPage = () => {
|
|
59 |
conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
60 |
(conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
|
61 |
|
62 |
-
|
|
|
|
|
63 |
|
64 |
const deadlineDate = safeParseISO(conf.deadline);
|
65 |
const startDate = safeParseISO(conf.start);
|
@@ -93,7 +97,9 @@ const CalendarPage = () => {
|
|
93 |
conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
94 |
(conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
|
95 |
|
96 |
-
|
|
|
|
|
97 |
return acc;
|
98 |
}
|
99 |
|
@@ -223,6 +229,7 @@ const CalendarPage = () => {
|
|
223 |
return (
|
224 |
<div className="min-h-screen bg-neutral-light">
|
225 |
<Header onSearch={setSearchQuery} />
|
|
|
226 |
<div className="p-6">
|
227 |
<div className="max-w-7xl mx-auto">
|
228 |
<div className="flex flex-col items-center mb-8">
|
@@ -282,7 +289,7 @@ const CalendarPage = () => {
|
|
282 |
row: "flex w-full mt-2",
|
283 |
cell: `h-10 w-10 text-center text-sm p-0 relative focus-within:relative focus-within:z-20
|
284 |
[&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md
|
285 |
-
last:[&:has([aria-selected])]:rounded-r-md hover:bg-neutral-50
|
286 |
day: "h-10 w-10 p-0 font-normal hover:bg-neutral-100 rounded-lg transition-colors",
|
287 |
day_today: "bg-neutral-100 text-primary font-semibold",
|
288 |
nav: "space-x-1 flex items-center",
|
|
|
6 |
import { parseISO, format, isValid, isSameMonth, isSameYear, isSameDay } from "date-fns";
|
7 |
import { Toggle } from "@/components/ui/toggle";
|
8 |
import Header from "@/components/Header";
|
9 |
+
import FilterBar from "@/components/FilterBar";
|
10 |
import {
|
11 |
Dialog,
|
12 |
DialogContent,
|
|
|
22 |
|
23 |
const CalendarPage = () => {
|
24 |
const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
|
25 |
+
const [isYearView, setIsYearView] = useState(true);
|
26 |
const [searchQuery, setSearchQuery] = useState("");
|
27 |
+
const [selectedTag, setSelectedTag] = useState("All");
|
28 |
const [selectedDayEvents, setSelectedDayEvents] = useState<{ date: Date | null, events: { deadlines: Conference[], conferences: Conference[] } }>({
|
29 |
date: null,
|
30 |
events: { deadlines: [], conferences: [] }
|
|
|
61 |
conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
62 |
(conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
|
63 |
|
64 |
+
const matchesTag = selectedTag === "All" || (Array.isArray(conf.tags) && conf.tags.includes(selectedTag));
|
65 |
+
|
66 |
+
if (!matchesSearch || !matchesTag) return false;
|
67 |
|
68 |
const deadlineDate = safeParseISO(conf.deadline);
|
69 |
const startDate = safeParseISO(conf.start);
|
|
|
97 |
conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
98 |
(conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
|
99 |
|
100 |
+
const matchesTag = selectedTag === "All" || (Array.isArray(conf.tags) && conf.tags.includes(selectedTag));
|
101 |
+
|
102 |
+
if (!matchesSearch || !matchesTag) {
|
103 |
return acc;
|
104 |
}
|
105 |
|
|
|
229 |
return (
|
230 |
<div className="min-h-screen bg-neutral-light">
|
231 |
<Header onSearch={setSearchQuery} />
|
232 |
+
<FilterBar selectedTag={selectedTag} onTagSelect={setSelectedTag} />
|
233 |
<div className="p-6">
|
234 |
<div className="max-w-7xl mx-auto">
|
235 |
<div className="flex flex-col items-center mb-8">
|
|
|
289 |
row: "flex w-full mt-2",
|
290 |
cell: `h-10 w-10 text-center text-sm p-0 relative focus-within:relative focus-within:z-20
|
291 |
[&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md
|
292 |
+
last:[&:has([aria-selected])]:rounded-r-md hover:bg-neutral-50",
|
293 |
day: "h-10 w-10 p-0 font-normal hover:bg-neutral-100 rounded-lg transition-colors",
|
294 |
day_today: "bg-neutral-100 text-primary font-semibold",
|
295 |
nav: "space-x-1 flex items-center",
|