react-native-event-logger
Version:
A React Native event tracking library with debug capabilities
115 lines • 4.78 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from "react";
import { View, Text, Animated, StyleSheet, TouchableWithoutFeedback, } from "react-native";
import { Colors } from "../constants/colors";
const ListAccordion = ({ title, children, eventTime, validationError, eventType }) => {
const [collapsed, setCollapsed] = useState(true);
const [animation] = useState(new Animated.Value(0));
const getTimeAgo = (timestamp) => {
const eventDate = new Date(timestamp);
const now = new Date();
const diffInSeconds = Math.floor((now.getTime() - eventDate.getTime()) / 1000);
const intervals = [
{ label: "year", seconds: 31536000 },
{ label: "month", seconds: 2592000 },
{ label: "day", seconds: 86400 },
{ label: "hr", seconds: 3600 },
{ label: "min", seconds: 60 },
{ label: "sec", seconds: 1 },
];
const isFuture = diffInSeconds < 0;
const seconds = Math.abs(diffInSeconds);
for (const interval of intervals) {
const count = Math.floor(seconds / interval.seconds);
if (count > 0) {
return isFuture
? `in ${count} ${interval.label}${count !== 1 ? "s" : ""}`
: `${count} ${interval.label}${count !== 1 ? "s" : ""} ago`;
}
}
return isFuture ? "in a moment" : "just now";
};
const toggleCollapse = () => {
Animated.timing(animation, {
toValue: collapsed ? 1 : 0,
duration: 300,
useNativeDriver: true, // Only animate transform/opacity
}).start();
setCollapsed(!collapsed);
};
const scaleY = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
return (_jsxs(View, { children: [_jsx(TouchableWithoutFeedback, Object.assign({ onPress: toggleCollapse }, { children: _jsxs(View, Object.assign({ style: [
styles.header,
validationError && styles.headerError,
collapsed && {
borderBottomEndRadius: 10,
borderBottomStartRadius: 10,
},
] }, { children: [_jsxs(View, Object.assign({ style: styles.headerContent }, { children: [_jsxs(View, Object.assign({ style: styles.titleContainer }, { children: [_jsx(Text, Object.assign({ style: [styles.title, validationError && styles.titleError] }, { children: title })), eventType && (_jsx(Text, Object.assign({ style: [styles.eventTypeText, validationError && styles.titleError] }, { children: `EventType: ${eventType}` })))] })), _jsx(Text, Object.assign({ style: styles.timeText }, { children: getTimeAgo(eventTime) }))] })), validationError && (_jsxs(Text, Object.assign({ style: styles.errorText }, { children: ["\u26A0\uFE0F ", validationError] })))] })) })), !collapsed && (_jsx(Animated.View, Object.assign({ style: { transform: [{ scaleY }], overflow: "hidden" } }, { children: _jsx(View, Object.assign({ style: styles.childrenStyle }, { children: children })) })))] }));
};
const styles = StyleSheet.create({
header: {
paddingHorizontal: 10,
paddingVertical: 20,
marginTop: 10,
borderTopEndRadius: 10,
borderTopStartRadius: 10,
backgroundColor: Colors.background.tertiary,
elevation: 2,
},
headerError: {
backgroundColor: Colors.background.ErrorRed,
borderLeftWidth: 4,
borderLeftColor: Colors.error,
},
headerContent: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
},
titleContainer: {
flex: 1,
marginRight: 10,
},
title: {
fontSize: 18,
fontWeight: "600",
color: Colors.text.secondary,
},
eventTypeText: {
fontSize: 14,
color: Colors.text.muted,
fontWeight: "500",
marginTop: 4,
letterSpacing: 0.5,
},
titleError: {
color: Colors.error,
},
timeText: {
fontSize: 14,
lineHeight: 20,
color: Colors.text.secondary,
},
errorText: {
fontSize: 14,
color: Colors.error,
fontWeight: "500",
marginTop: 8,
paddingTop: 8,
borderTopWidth: 1,
borderTopColor: Colors.background.lightRed, // Lighter red border
},
childrenStyle: {
paddingHorizontal: 10,
paddingVertical: 20,
backgroundColor: Colors.background.secondary,
borderBottomEndRadius: 10,
borderBottomStartRadius: 10,
},
});
export default ListAccordion;
//# sourceMappingURL=ListAccordion.js.map