refactor: extract shared EventCardBase component

- Create EventCardBase with common layout, icons (calendar, clock, repeat), and formatting functions
- Refactor EventCard and ProposedEventCard to use EventCardBase
- Add event details to delete action responses for better UX
- Include event title in delete confirmation message
This commit is contained in:
2026-01-05 19:27:33 +01:00
parent 24ab6f0420
commit 8e58ab4249
5 changed files with 235 additions and 192 deletions

View File

@@ -0,0 +1,141 @@
import { View, Text } from "react-native";
import { Feather } from "@expo/vector-icons";
import { ReactNode } from "react";
import currentTheme from "../Themes";
type EventCardBaseProps = {
className?: string;
title: string;
startTime: Date;
endTime: Date;
description?: string;
isRecurring?: boolean;
children?: ReactNode;
};
function formatDate(date: Date): string {
const d = new Date(date);
return d.toLocaleDateString("de-DE", {
weekday: "short",
day: "2-digit",
month: "2-digit",
year: "numeric",
});
}
function formatTime(date: Date): string {
const d = new Date(date);
return d.toLocaleTimeString("de-DE", {
hour: "2-digit",
minute: "2-digit",
});
}
function formatDuration(start: Date, end: Date): string {
const startDate = new Date(start);
const endDate = new Date(end);
const diffMs = endDate.getTime() - startDate.getTime();
const diffMins = Math.round(diffMs / 60000);
if (diffMins < 60) {
return `${diffMins} min`;
}
const hours = Math.floor(diffMins / 60);
const mins = diffMins % 60;
if (mins === 0) {
return hours === 1 ? "1 Std" : `${hours} Std`;
}
return `${hours} Std ${mins} min`;
}
export const EventCardBase = ({
className,
title,
startTime,
endTime,
description,
isRecurring,
children,
}: EventCardBaseProps) => {
return (
<View
className={`rounded-xl overflow-hidden ${className}`}
style={{ borderWidth: 2, borderColor: currentTheme.borderPrimary }}
>
{/* Header with title */}
<View
className="px-3 py-2"
style={{
backgroundColor: currentTheme.chatBot,
borderBottomWidth: 2,
borderBottomColor: currentTheme.borderPrimary,
}}
>
<Text className="font-bold text-base">{title}</Text>
</View>
{/* Content */}
<View className="px-3 py-2 bg-white">
{/* Date */}
<View className="flex-row items-center mb-1">
<Feather
name="calendar"
size={16}
color={currentTheme.textPrimary}
style={{ marginRight: 8 }}
/>
<Text style={{ color: currentTheme.textPrimary }}>
{formatDate(startTime)}
</Text>
</View>
{/* Time with duration */}
<View className="flex-row items-center mb-1">
<Feather
name="clock"
size={16}
color={currentTheme.textPrimary}
style={{ marginRight: 8 }}
/>
<Text style={{ color: currentTheme.textPrimary }}>
{formatTime(startTime)} - {formatTime(endTime)} (
{formatDuration(startTime, endTime)})
</Text>
</View>
{/* Recurring indicator */}
{isRecurring && (
<View className="flex-row items-center mb-1">
<Feather
name="repeat"
size={16}
color={currentTheme.textPrimary}
style={{ marginRight: 8 }}
/>
<Text style={{ color: currentTheme.textPrimary }}>
Wiederkehrend
</Text>
</View>
)}
{/* Description */}
{description && (
<Text
style={{ color: currentTheme.textPrimary }}
className="text-sm mt-1"
>
{description}
</Text>
)}
{/* Action buttons slot */}
{children}
</View>
</View>
);
};
export default EventCardBase;