HoshiAI-app/components/user-test.tsx

108 lines
3.3 KiB
TypeScript

import { UserTestResponse } from "@/api/types";
import formatISODate from "@/utils/format-iso-date";
import { getUserTestStatus } from "@/utils/get-user-test-status";
import getUserTestTitle from "@/utils/get-user-test-title";
import { FontAwesome5 } from "@expo/vector-icons";
import { Pressable, StyleSheet, View } from "react-native";
import { Badge, BadgeText } from "./ui/badge";
import { Divider } from "./ui/divider";
import Panel from "./ui/panel";
import { Skeleton } from "./ui/skeleton";
import { ThemedText } from "./ui/themed-text";
type BadgeType = "muted" | "success" | "info" | "warning" | "error";
enum TestStatus {
Completed = "Completed",
Expired = "Expired",
InProgress = "In Progress",
}
interface UserTestProps {
userTest?: UserTestResponse;
onPress?: (userTest: UserTestResponse) => void;
}
const UserTest = ({ userTest, onPress }: UserTestProps) => {
if (!userTest) return <Skeleton className="h-20" />;
const title = getUserTestTitle(userTest);
const testStatus = getUserTestStatus(userTest);
let scoreType: BadgeType = "muted";
if (userTest.is_completed || !userTest.is_available) {
if (userTest.score >= 80) scoreType = "success";
else if (userTest.score >= 60) scoreType = "info";
else if (userTest.score >= 40) scoreType = "warning";
else if (userTest.score >= 0) scoreType = "error";
}
const successAnswers = userTest.answers.filter(answer => answer.is_correct).length;
let testStatusType: BadgeType = "warning";
if (testStatus === TestStatus.Completed) testStatusType = "success";
else if (testStatus === TestStatus.Expired) testStatusType = "error";
return (
<Pressable onPress={() => onPress?.(userTest)}>
<Panel>
<View className="justify-between flex-row items-center">
<Badge action={testStatusType}>
<BadgeText>
<FontAwesome5 name="info-circle" /> {testStatus}
</BadgeText>
</Badge>
<Badge action={scoreType}>
<BadgeText>
<FontAwesome5 name="star" /> {userTest.score}
</BadgeText>
</Badge>
</View>
<Divider className="mt-2 mb-2" />
<ThemedText style={styles.testTitle}>{title}</ThemedText>
<View className="flex-row flex-wrap">
<View className="mr-6">
<View>
<ThemedText type="meta">Started at:</ThemedText>
</View>
<View>
<ThemedText>{formatISODate(userTest.created_at)}</ThemedText>
</View>
</View>
<View>
<View>
<ThemedText type="meta">Closed at:</ThemedText>
</View>
<View>
<ThemedText>{formatISODate(userTest.closed_at)}</ThemedText>
</View>
</View>
</View>
<Divider className="mt-2 mb-2" />
<View className="justify-between flex-row items-center">
<ThemedText type="meta">
{userTest.answers.length} Questions
</ThemedText>
<ThemedText type="meta">
{successAnswers} / {userTest.answers.length} Correct
</ThemedText>
</View>
</Panel>
</Pressable>
);
};
const styles = StyleSheet.create({
testTitle: {
fontSize: 18,
fontWeight: "600",
marginBottom: 10,
},
});
export default UserTest;