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:
141
apps/client/src/components/EventCardBase.tsx
Normal file
141
apps/client/src/components/EventCardBase.tsx
Normal 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;
|
||||
Reference in New Issue
Block a user