mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-29 18:28:06 +03:00
96 lines
3.8 KiB
TypeScript
96 lines
3.8 KiB
TypeScript
import React from "react";
|
|
import {Platform, TouchableOpacity, View} from "react-native";
|
|
|
|
import {useNavigation} from "@react-navigation/native";
|
|
import {createNativeStackNavigator} from "@react-navigation/native-stack";
|
|
|
|
import {Card, Paragraph, Text, Title, useTheme} from "react-native-paper";
|
|
import {SmartphoneNfc, SquareAsterisk, SquarePlus} from "lucide-react-native";
|
|
|
|
import ManualCardEntry from "./ManualCardEntry";
|
|
import PhysicalCardScan from "./PhyscialCardScan";
|
|
|
|
const Stack = createNativeStackNavigator();
|
|
|
|
function CardAddModal() {
|
|
return (
|
|
<Stack.Navigator initialRouteName="Select">
|
|
<Stack.Screen name="Select" component={CardAddMethodSelector} options={{headerShown: false}}/>
|
|
|
|
<Stack.Screen name="Scan" component={PhysicalCardScan} options={{title: "Add Physical Card"}}/>
|
|
<Stack.Screen name="Manual" component={ManualCardEntry} options={{title: "Add Card Manually"}}/>
|
|
</Stack.Navigator>
|
|
)
|
|
}
|
|
|
|
function CardAddMethodSelector() {
|
|
const theme = useTheme();
|
|
const navigation: any = useNavigation();
|
|
|
|
return (
|
|
<View style={{paddingHorizontal: 15, paddingTop: 90, gap: 8}}>
|
|
<View style={{paddingBottom: 25, gap: 5}}>
|
|
<Title style={{textAlign: "center", fontSize: 32, fontWeight: "bold"}}>Add new Card</Title>
|
|
<Paragraph style={{textAlign: "center"}}>AMNet supports scanning physical cards, entering details
|
|
manually or generating new ones.</Paragraph>
|
|
</View>
|
|
|
|
<MethodCard color={theme.colors.primary}
|
|
icon={<SmartphoneNfc/>}
|
|
title="Scan Physical Card"
|
|
description="Amusement IC or Transport cards supported"
|
|
onPress={() => navigation.navigate('Scan')}/>
|
|
|
|
<View></View>
|
|
|
|
<MethodCard color={theme.colors.secondary}
|
|
icon={<SquareAsterisk/>}
|
|
title="Enter Details Manually"
|
|
//description="Manually enter card details (or generate a new one)"
|
|
onPress={() => navigation.navigate('Manual')}/>
|
|
|
|
<MethodCard color="cornflowerblue"
|
|
icon={<SquarePlus/>}
|
|
title="Generate New Card"
|
|
//description="Create a card from scratch"
|
|
onPress={() => navigation.navigate('Manual', {autoGenerate: true})}/>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
function MethodCard(props: {
|
|
title: string,
|
|
description?: string,
|
|
color: string,
|
|
icon: React.ReactElement,
|
|
onPress: () => void
|
|
}) {
|
|
const theme = useTheme();
|
|
const large = props.description?.length > 0;
|
|
|
|
return (
|
|
<TouchableOpacity onPress={() => props.onPress()}>
|
|
<Card mode={theme.dark ? "elevated" : "contained"}>
|
|
<Card.Content style={{display: "flex", flexDirection: "row", alignItems: "center", gap: 15}}>
|
|
<View style={{
|
|
borderRadius: large ? 10 : 5,
|
|
height: large ? 50 : 30,
|
|
width: large ? 50 : 30,
|
|
backgroundColor: props.color,
|
|
justifyContent: "center",
|
|
alignItems: "center"
|
|
}}>
|
|
{React.cloneElement(props.icon, {size: large ? 24 : 16, color: theme.colors.surfaceVariant})}
|
|
</View>
|
|
<View style={{flexShrink: 1}}>
|
|
<Text style={{fontSize: large ? 16 : 14}}>{props.title}</Text>
|
|
{props.description && (<Paragraph style={{fontSize: 12}}>{props.description}</Paragraph>)}
|
|
</View>
|
|
</Card.Content>
|
|
</Card>
|
|
</TouchableOpacity>
|
|
)
|
|
}
|
|
|
|
export default Platform.OS === 'ios' ? CardAddModal : ManualCardEntry;
|