refactor: add CardBase and ModalBase components
- Add CardBase: reusable card with header, content, footer - Configurable via props: padding, border, text size, background - Add ModalBase: modal wrapper using CardBase internally - Provides backdrop, click-outside-to-close, Android back button - Refactor EventCardBase to use CardBase - Refactor DeleteEventModal to use ModalBase - Refactor EventOverlay (calendar.tsx) to use ModalBase - Update CLAUDE.md with component documentation
This commit is contained in:
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
Animated,
|
||||
Modal,
|
||||
Pressable,
|
||||
Text,
|
||||
View,
|
||||
ScrollView,
|
||||
} from "react-native";
|
||||
import { Animated, Modal, Pressable, Text, View } from "react-native";
|
||||
import {
|
||||
DAYS,
|
||||
MONTHS,
|
||||
@@ -16,6 +9,7 @@ import {
|
||||
import Header from "../../components/Header";
|
||||
import { EventCard } from "../../components/EventCard";
|
||||
import { DeleteEventModal } from "../../components/DeleteEventModal";
|
||||
import { ModalBase } from "../../components/ModalBase";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
@@ -263,7 +257,6 @@ const EventOverlay = ({
|
||||
onEditEvent,
|
||||
onDeleteEvent,
|
||||
}: EventOverlayProps) => {
|
||||
const { theme } = useThemeStore();
|
||||
if (!date) return null;
|
||||
|
||||
const dateString = date.toLocaleDateString("de-DE", {
|
||||
@@ -273,75 +266,27 @@ const EventOverlay = ({
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
const subtitle = `${events.length} ${events.length === 1 ? "Termin" : "Termine"}`;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
<ModalBase
|
||||
visible={visible}
|
||||
transparent={true}
|
||||
animationType="fade"
|
||||
onRequestClose={onClose}
|
||||
onClose={onClose}
|
||||
title={dateString}
|
||||
subtitle={subtitle}
|
||||
footer={{ label: "Schliessen", onPress: onClose }}
|
||||
scrollable={true}
|
||||
maxContentHeight={400}
|
||||
>
|
||||
<Pressable
|
||||
className="flex-1 justify-center items-center"
|
||||
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||
onPress={onClose}
|
||||
>
|
||||
<Pressable
|
||||
className="w-11/12 max-h-3/4 rounded-2xl overflow-hidden"
|
||||
style={{
|
||||
backgroundColor: theme.primeBg,
|
||||
borderWidth: 4,
|
||||
borderColor: theme.borderPrimary,
|
||||
}}
|
||||
onPress={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<View
|
||||
className="px-4 py-3"
|
||||
style={{
|
||||
backgroundColor: theme.chatBot,
|
||||
borderBottomWidth: 3,
|
||||
borderBottomColor: theme.borderPrimary,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
className="font-bold text-lg"
|
||||
style={{ color: theme.textPrimary }}
|
||||
>
|
||||
{dateString}
|
||||
</Text>
|
||||
<Text style={{ color: theme.textPrimary }}>
|
||||
{events.length} {events.length === 1 ? "Termin" : "Termine"}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Events List */}
|
||||
<ScrollView className="p-4" style={{ maxHeight: 400 }}>
|
||||
{events.map((event, index) => (
|
||||
<EventCard
|
||||
key={`${event.id}-${index}`}
|
||||
event={event}
|
||||
onEdit={() => onEditEvent(event)}
|
||||
onDelete={() => onDeleteEvent(event)}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
|
||||
{/* Close button */}
|
||||
<Pressable
|
||||
onPress={onClose}
|
||||
className="py-3 items-center"
|
||||
style={{
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: theme.placeholderBg,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.primeFg }} className="font-bold">
|
||||
Schließen
|
||||
</Text>
|
||||
</Pressable>
|
||||
</Pressable>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
{events.map((event, index) => (
|
||||
<EventCard
|
||||
key={`${event.id}-${index}`}
|
||||
event={event}
|
||||
onEdit={() => onEditEvent(event)}
|
||||
onDelete={() => onDeleteEvent(event)}
|
||||
/>
|
||||
))}
|
||||
</ModalBase>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user