diff --git a/web/src/components/ActivityCalendar/CalendarCell.tsx b/web/src/components/ActivityCalendar/CalendarCell.tsx
index 5d47dc56..175b5ddc 100644
--- a/web/src/components/ActivityCalendar/CalendarCell.tsx
+++ b/web/src/components/ActivityCalendar/CalendarCell.tsx
@@ -3,7 +3,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip
import { cn } from "@/lib/utils";
import { DEFAULT_CELL_SIZE, SMALL_CELL_SIZE } from "./constants";
import type { CalendarDayCell, CalendarSize } from "./types";
-import { getCellIntensityClass } from "./utils";
+import { getCalendarCellStateClass, getCellIntensityClass } from "./utils";
export interface CalendarCellProps {
day: CalendarDayCell;
@@ -44,8 +44,7 @@ export const CalendarCell = memo((props: CalendarCellProps) => {
const buttonClasses = cn(
baseClasses,
intensityClass,
- day.isToday && "ring-2 ring-primary/30 ring-offset-1 font-semibold z-10",
- day.isSelected && "ring-2 ring-primary ring-offset-1 font-bold z-10",
+ getCalendarCellStateClass(day),
isInteractive ? "cursor-pointer hover:bg-muted/40 hover:border-border/30" : "cursor-default",
);
diff --git a/web/src/components/ActivityCalendar/MonthCalendar.tsx b/web/src/components/ActivityCalendar/MonthCalendar.tsx
index 891a285b..3c3e9176 100644
--- a/web/src/components/ActivityCalendar/MonthCalendar.tsx
+++ b/web/src/components/ActivityCalendar/MonthCalendar.tsx
@@ -23,7 +23,7 @@ const WeekdayHeader = memo(({ weekDays, size }: WeekdayHeaderProps) => (
{weekDays.map((label, index) => (
@@ -35,11 +35,12 @@ const WeekdayHeader = memo(({ weekDays, size }: WeekdayHeaderProps) => (
WeekdayHeader.displayName = "WeekdayHeader";
export const MonthCalendar = memo((props: MonthCalendarProps) => {
- const { month, data, maxCount, size = "default", onClick, className, disableTooltips = false } = props;
+ const { month, data, maxCount, size = "default", onClick, selectedDate, className, disableTooltips = false } = props;
const t = useTranslate();
const { generalSetting } = useInstance();
const today = useTodayDate();
const weekDays = useWeekdayLabels();
+ const gridStyle = GRID_STYLES[size];
const { weeks, weekDays: rotatedWeekDays } = useCalendarMatrix({
month,
@@ -47,7 +48,7 @@ export const MonthCalendar = memo((props: MonthCalendarProps) => {
weekDays,
weekStartDayOffset: generalSetting.weekStartDayOffset,
today,
- selectedDate: "",
+ selectedDate: selectedDate ?? "",
});
const flatDays = useMemo(() => weeks.flatMap((week) => week.days), [weeks]);
@@ -56,7 +57,7 @@ export const MonthCalendar = memo((props: MonthCalendarProps) => {
-
+
{flatDays.map((day) => (
;
+ data: CalendarData;
maxCount: number;
onDateClick: (date: string) => void;
}
@@ -87,7 +87,7 @@ export const YearCalendar = memo(({ selectedYear, data, onYearChange, onDateClic
const currentYear = useMemo(() => new Date().getFullYear(), []);
const yearData = useMemo(() => filterDataByYear(data, selectedYear), [data, selectedYear]);
const months = useMemo(() => generateMonthsForYear(selectedYear), [selectedYear]);
- const yearMaxCount = useMemo(() => calculateYearMaxCount(yearData), [yearData]);
+ const yearMaxCount = useMemo(() => calculateMaxCount(yearData), [yearData]);
const canGoPrev = selectedYear > MIN_YEAR;
const canGoNext = selectedYear < getMaxYear();
diff --git a/web/src/components/ActivityCalendar/constants.ts b/web/src/components/ActivityCalendar/constants.ts
index c0913b96..de457971 100644
--- a/web/src/components/ActivityCalendar/constants.ts
+++ b/web/src/components/ActivityCalendar/constants.ts
@@ -1,6 +1,5 @@
export const DAYS_IN_WEEK = 7;
export const MONTHS_IN_YEAR = 12;
-export const WEEKEND_DAYS = [0, 6] as const;
export const MIN_COUNT = 1;
export const MIN_YEAR = 1970;
diff --git a/web/src/components/ActivityCalendar/types.ts b/web/src/components/ActivityCalendar/types.ts
index 306b21b9..119b0d07 100644
--- a/web/src/components/ActivityCalendar/types.ts
+++ b/web/src/components/ActivityCalendar/types.ts
@@ -1,4 +1,5 @@
export type CalendarSize = "default" | "small";
+export type CalendarData = Record;
export interface CalendarDayCell {
date: string;
@@ -7,7 +8,6 @@ export interface CalendarDayCell {
isCurrentMonth: boolean;
isToday: boolean;
isSelected: boolean;
- isWeekend: boolean;
}
export interface CalendarDayRow {
@@ -17,22 +17,22 @@ export interface CalendarDayRow {
export interface CalendarMatrixResult {
weeks: CalendarDayRow[];
weekDays: string[];
- maxCount: number;
}
export interface MonthCalendarProps {
month: string;
- data: Record;
+ data: CalendarData;
maxCount: number;
size?: CalendarSize;
onClick?: (date: string) => void;
+ selectedDate?: string;
className?: string;
disableTooltips?: boolean;
}
export interface YearCalendarProps {
selectedYear: number;
- data: Record;
+ data: CalendarData;
onYearChange: (year: number) => void;
onDateClick: (date: string) => void;
className?: string;
diff --git a/web/src/components/ActivityCalendar/useCalendar.ts b/web/src/components/ActivityCalendar/useCalendar.ts
index 783767e4..cf45dbee 100644
--- a/web/src/components/ActivityCalendar/useCalendar.ts
+++ b/web/src/components/ActivityCalendar/useCalendar.ts
@@ -1,11 +1,11 @@
import dayjs from "dayjs";
import { useMemo } from "react";
-import { DAYS_IN_WEEK, MIN_COUNT, WEEKEND_DAYS } from "./constants";
-import type { CalendarDayCell, CalendarMatrixResult } from "./types";
+import { DAYS_IN_WEEK } from "./constants";
+import type { CalendarData, CalendarDayCell, CalendarMatrixResult } from "./types";
export interface UseCalendarMatrixParams {
month: string;
- data: Record;
+ data: CalendarData;
weekDays: string[];
weekStartDayOffset: number;
today: string;
@@ -15,7 +15,7 @@ export interface UseCalendarMatrixParams {
const createCalendarDayCell = (
current: dayjs.Dayjs,
monthKey: string,
- data: Record,
+ data: CalendarData,
today: string,
selectedDate: string,
): CalendarDayCell => {
@@ -30,7 +30,6 @@ const createCalendarDayCell = (
isCurrentMonth,
isToday: isoDate === today,
isSelected: isoDate === selectedDate,
- isWeekend: WEEKEND_DAYS.includes(current.day() as 0 | 6),
};
};
@@ -68,7 +67,6 @@ export const useCalendarMatrix = ({
const { calendarStart, dayCount } = calculateCalendarBoundaries(monthStart, weekStartDayOffset);
const weeks: CalendarMatrixResult["weeks"] = [];
- let maxCount = 0;
// Iterate through each day in the calendar grid
for (let index = 0; index < dayCount; index += 1) {
@@ -82,13 +80,11 @@ export const useCalendarMatrix = ({
// Create the day cell object with data and status flags
const dayCell = createCalendarDayCell(current, monthKey, data, today, selectedDate);
weeks[weekIndex].days.push(dayCell);
- maxCount = Math.max(maxCount, dayCell.count);
}
return {
weeks,
weekDays: rotatedWeekDays,
- maxCount: Math.max(maxCount, MIN_COUNT),
};
}, [month, data, weekDays, weekStartDayOffset, today, selectedDate]);
};
diff --git a/web/src/components/ActivityCalendar/utils.ts b/web/src/components/ActivityCalendar/utils.ts
index 0ce1029d..368c26ab 100644
--- a/web/src/components/ActivityCalendar/utils.ts
+++ b/web/src/components/ActivityCalendar/utils.ts
@@ -1,9 +1,10 @@
import dayjs from "dayjs";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
+import { cn } from "@/lib/utils";
import { useTranslate } from "@/utils/i18n";
import { CELL_STYLES, INTENSITY_THRESHOLDS, MIN_COUNT, MONTHS_IN_YEAR } from "./constants";
-import type { CalendarDayCell } from "./types";
+import type { CalendarData, CalendarDayCell } from "./types";
dayjs.extend(isSameOrAfter);
dayjs.extend(isSameOrBefore);
@@ -22,11 +23,15 @@ export const getCellIntensityClass = (day: CalendarDayCell, maxCount: number): s
return CELL_STYLES.MINIMAL;
};
+export const getCalendarCellStateClass = (day: Pick): string => {
+ return cn(day.isToday && "font-semibold z-10", day.isSelected && "font-bold z-10");
+};
+
export const generateMonthsForYear = (year: number): string[] => {
return Array.from({ length: MONTHS_IN_YEAR }, (_, i) => dayjs(`${year}-01-01`).add(i, "month").format("YYYY-MM"));
};
-export const calculateYearMaxCount = (data: Record): number => {
+export const calculateMaxCount = (data: CalendarData): number => {
let max = 0;
for (const count of Object.values(data)) {
max = Math.max(max, count);
@@ -55,10 +60,6 @@ export const filterDataByYear = (data: Record, year: number): Re
return filtered;
};
-export const hasActivityData = (data: Record): boolean => {
- return Object.values(data).some((count) => count > 0);
-};
-
export const getTooltipText = (count: number, date: string, t: TranslateFunction): string => {
if (count === 0) {
return date;
diff --git a/web/src/components/MemoEditor/components/AudioRecorderPanel.tsx b/web/src/components/MemoEditor/components/AudioRecorderPanel.tsx
index 6b7c49fb..ae95722a 100644
--- a/web/src/components/MemoEditor/components/AudioRecorderPanel.tsx
+++ b/web/src/components/MemoEditor/components/AudioRecorderPanel.tsx
@@ -15,30 +15,29 @@ export const AudioRecorderPanel: FC = ({ audioRecorder,
return (
-
+
{isRequestingPermission ? t("editor.audio-recorder.requesting-permission") : t("editor.audio-recorder.recording")}
-
-
-
- {isRequestingPermission ? (
-
- ) : (
-
- )}
- {formatAudioTime(elapsedSeconds)}
+
+ {isRequestingPermission ? (
+
+ ) : (
+
+ )}
+ {formatAudioTime(elapsedSeconds)}
+
-