Compare commits

..

2 Commits

Author SHA1 Message Date
bdb3effaf0 feat: calendar component 2025-04-20 14:04:39 +03:00
97879cc41b feat: fixed todos in calendar 2025-04-17 12:54:08 +03:00
4 changed files with 47 additions and 15 deletions

View File

@@ -1,9 +1,26 @@
import { withTitle } from "@/constructors/Component";
import { UrlsTitle } from "@/enums/urls";
import { cn } from "@/utils/class-merge";
import { BackwardIcon } from "@heroicons/react/24/solid";
import { FunctionComponent, h } from "preact";
import { useState } from "preact/hooks";
interface BackButtonProps {
selectedDate: Date;
onClick: () => void;
}
const BackButton: FunctionComponent<BackButtonProps> = ({ selectedDate, onClick }: BackButtonProps) => {
const currentDate = new Date();
return currentDate.getMonth() !== selectedDate.getMonth() ? (
<div
class="fixed bottom-4 left-8 hidden aspect-square h-24 cursor-pointer flex-col items-center justify-center rounded-full bg-[rgb(251,194,199,0.53)] shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] hover:bg-[rgb(251,194,199,0.7)] md:flex"
onClick={onClick}
>
<BackwardIcon class="size-8 text-sm text-white" />
</div>
) : null;
};
type MarkedDateType = "event" | "holiday" | "important" | string;
type MarkedDates = Record<string, MarkedDateType>;
@@ -44,7 +61,7 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
const getFirstDayOfMonth = (year: number, month: number): number => {
const day = new Date(year, month, 1).getDay();
return day === 0 ? 6 : day - 1;
return day === 0 ? 6 : day;
};
const handlePrevMonth = (): void => {
@@ -60,7 +77,7 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
setCurrentDate(new Date(date.getFullYear(), date.getMonth(), 1));
}
setSelectedDate(date);
onDateSelect?.(date);
onDateSelect(date);
};
const isDateMarked = (date: Date): MarkedDateType | undefined => {
@@ -70,7 +87,7 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
const getLastDayOfMonth = (year: number, month: number): number => {
const day = new Date(year, month + 1, 0).getDay();
return day === 0 ? 6 : day - 1;
return day === 0 ? 6 : day;
};
const renderDays = (): h.JSX.Element[] => {
@@ -84,12 +101,11 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
const days: h.JSX.Element[] = [];
// Дни предыдущего месяца
//TODO: work on click on 31 march
const prevMonthDays = getDaysInMonth(year, month - 1);
const daysFromPrevMonth = firstDayOfMonth === 0 ? 6 : firstDayOfMonth;
for (let i = daysFromPrevMonth - 1; i >= 0; i--) {
const day = prevMonthDays - i;
const date = new Date(year, month - 1, day + 1);
const date = new Date(year, month - 1, day);
const dateStr = date.toISOString().split("T")[0];
const isSelected = selectedDate?.toISOString().split("T")[0] === dateStr;
const markType = isDateMarked(date);
@@ -122,7 +138,7 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
// Дни текущего месяца
for (let day = 1; day <= daysInMonth; day++) {
const date = new Date(year, month, day + 1);
const date = new Date(year, month, day);
const dateStr = date.toISOString().split("T")[0];
const isSelected = selectedDate?.toISOString().split("T")[0] === dateStr;
const markType = isDateMarked(date);
@@ -166,9 +182,9 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
}
// Дни следующего месяца
const daysToAdd = 6 - (lastDayOfMonth === 6 ? 4 : lastDayOfMonth);
const daysToAdd = 6 - (lastDayOfMonth === 6 ? 3 : lastDayOfMonth);
for (let day = 1; day <= daysToAdd; day++) {
const date = new Date(year, month + 1, day + 1);
const date = new Date(year, month + 1, day);
const dateStr = date.toISOString().split("T")[0];
const isSelected = selectedDate?.toISOString().split("T")[0] === dateStr;
const markType = isDateMarked(date);
@@ -203,7 +219,7 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
};
return (
<div className={`flex flex-col ${className}`}>
<div className={`flex w-full flex-col ${className}`}>
<div className="mb-4 flex items-center justify-between px-2">
<button
onClick={handlePrevMonth}
@@ -235,7 +251,6 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
</svg>
</button>
</div>
<div className="mb-2 grid grid-cols-7 gap-1 text-center text-sm font-medium text-gray-500">
{dayNames.map((day) => (
<div key={day} className="flex h-10 items-center justify-center">
@@ -243,10 +258,10 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
</div>
))}
</div>
<div className="grid flex-1 grid-cols-7 gap-1">{renderDays()}</div>
<BackButton selectedDate={currentDate} onClick={() => setCurrentDate(new Date())} />
</div>
);
};
export default withTitle(UrlsTitle.CALENDAR, BigCalendar);
export default BigCalendar;

View File

@@ -14,7 +14,7 @@ const ProfilePage: FunctionComponent = () => {
<Router>
<Route path="/settings" component={lazy(() => import("./profile_settings"))} />
<Route path="/tasks" component={lazy(() => import("./profile_tasks"))} />
<Route path="/calendar" component={lazy(() => import("./calendar"))} />
<Route path="/calendar" component={lazy(() => import("./profile_calendar"))} />
<Route
default
component={() => {

View File

@@ -0,0 +1,17 @@
import BigCalendar from "@/components/calendar";
import { withTitle } from "@/constructors/Component";
import { UrlsTitle } from "@/enums/urls";
import { FunctionComponent } from "preact";
const ProfileCalendar: FunctionComponent = () => {
const onDateSelect = (date: Date) => {
console.log(date);
};
return (
<div class="flex w-full flex-col items-center">
<BigCalendar onDateSelect={onDateSelect} />
</div>
);
};
export default withTitle(UrlsTitle.CALENDAR, ProfileCalendar);