mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-27 17:27:55 +03:00
106 lines
4.3 KiB
TypeScript
106 lines
4.3 KiB
TypeScript
import NfcManager from "react-native-nfc-manager";
|
|
|
|
import React, {useEffect, useState} from "react";
|
|
import {Platform, TouchableOpacity, View} from "react-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({navigation}) {
|
|
const theme = useTheme();
|
|
const [nfcSupported, setNfcSupported] = useState<boolean | null>(null);
|
|
|
|
useEffect(() => {
|
|
NfcManager.isSupported().then(setNfcSupported);
|
|
}, []);
|
|
|
|
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>
|
|
|
|
{nfcSupported !== null && (
|
|
<>
|
|
<MethodCard color="#03a9f4"
|
|
icon={<SmartphoneNfc/>}
|
|
disabled={!nfcSupported}
|
|
title="Scan Physical Card"
|
|
description={nfcSupported ? "Amusement IC or Transport cards supported" : "NFC is not supported on this device"}
|
|
onPress={() => navigation.navigate('Scan')}/>
|
|
|
|
<View></View>
|
|
</>
|
|
)}
|
|
|
|
<MethodCard color={theme.colors.secondary}
|
|
icon={<SquareAsterisk/>}
|
|
title="Enter Details Manually"
|
|
onPress={() => navigation.navigate('Manual')}/>
|
|
|
|
<MethodCard color="#4caf50"
|
|
icon={<SquarePlus/>}
|
|
title="Generate New Card"
|
|
onPress={() => navigation.navigate('Manual', {autoGenerate: true})}/>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
function MethodCard(props: {
|
|
title: string,
|
|
description?: string,
|
|
color: string,
|
|
disabled?: boolean,
|
|
icon: React.ReactElement,
|
|
onPress: () => void
|
|
}) {
|
|
const theme = useTheme();
|
|
const large = props.description?.length > 0;
|
|
|
|
return (
|
|
<TouchableOpacity onPress={() => !props.disabled && props.onPress()} disabled={props.disabled}>
|
|
<Card mode={theme.dark ? "elevated" : "contained"} disabled={props.disabled}>
|
|
<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>
|
|
)
|
|
}
|
|
|
|
// the nfc library doesn't offer the same support for felica cards on android compared to ios...
|
|
export default Platform.OS === 'ios' ? CardAddModal : ManualCardEntry;
|