refactor aimecard to iccard

This commit is contained in:
ppc
2025-01-12 19:44:45 +00:00
parent adb60dd928
commit 3e3755471d
4 changed files with 99 additions and 52 deletions
+6 -5
View File
@@ -5,7 +5,7 @@ import {Button, useTheme} from "react-native-paper";
import {CreditCard, Plus} from "lucide-react-native";
import ContextMenu from "react-native-context-menu-view";
import {AimeCard} from "../components/AimeCard";
import {ICCard} from "../components/ICCard";
import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
import {AMCard} from "../models/AMCard";
@@ -21,19 +21,20 @@ function CardEntry(props: { card: AMCard, navigation: any }) {
}
switch (indexPath.toString()) {
// copy card
// copy card access code
case "0":
case "0,0":
await Clipboard.setStringAsync(props.card.code);
return;
// edit card
case "1,0":
props.navigation.navigate('add-card', {cardId: props.card.code, cardName: props.card.name});
props.navigation.navigate('edit-card', {cardId: props.card._id.toHexString()});
return;
// remove card
case "1,1":
realm.write(() => realm.delete(props.card));
AMCard.delete(realm, props.card);
return;
}
}, [realm, props.card, props.navigation]);
@@ -50,7 +51,7 @@ function CardEntry(props: { card: AMCard, navigation: any }) {
{title: "Edit Card", systemIcon: "square.and.pencil"},
{title: "Delete Card", destructive: true, systemIcon: "trash"}]
}]}>
<AimeCard card={props.card} showFullCardNumber/>
<ICCard card={props.card} showFullCardNumber/>
</ContextMenu>
);
}
+10 -11
View File
@@ -2,7 +2,6 @@ import {BSON} from "realm";
import React, {useCallback, useEffect, useLayoutEffect, useMemo, useState} from "react";
import {ActivityIndicator, Button, Paragraph, Title, useTheme} from "react-native-paper";
import {
Alert,
Platform,
RefreshControl,
ScrollView,
@@ -28,7 +27,7 @@ import {
import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
import {AMUIStatusAlert} from "../components/AMUIStatusAlert";
import {AMUICardDetail} from "../components/AMUICard";
import {AimeCard} from "../components/AimeCard";
import {ICCard} from "../components/ICCard";
import RealmContext from "../models/RealmContext";
import {AMServer} from "../models/AMServer";
@@ -193,11 +192,11 @@ export default function ServerCardIn({route, navigation}) {
<View style={styles.section}>
<Title style={styles.sectionTitle}>{server.gameId ? `Play ${getGameName(server.gameId)}` : "Selected Card"}</Title>
{selectedCard ? <>
<AimeCard actionDisabled
card={selectedCard}
actionIcon={<CircleCheck color="green" size={24}/>}>
<ICCard actionDisabled
card={selectedCard}
actionIcon={<CircleCheck color="green" size={24}/>}>
{serverDefaultCard?.code == selectedCard.code && <DefaultCardDetail/>}
</AimeCard>
</ICCard>
<Button textColor="white"
onPress={cardInCallback}
disabled={disableCardIn}
@@ -232,12 +231,12 @@ export default function ServerCardIn({route, navigation}) {
{unselectedCards.length
? unselectedCards.map((card: AMCard) => (
<AimeCard card={card}
key={card._id.toHexString()}
actionIcon={<CircleDot color={theme.colors.tertiary} size={24}/>}
onPress={() => setUserSelectedCard(card)}>
<ICCard card={card}
key={card._id.toHexString()}
actionIcon={<CircleDot color={theme.colors.tertiary} size={24}/>}
onPress={() => setUserSelectedCard(card)}>
{serverDefaultCard?.code == card.code && <DefaultCardDetail/>}
</AimeCard>))
</ICCard>))
: <View style={styles.emptyPlaceholderView}>
<EmptyStatePlaceholder message="No additional cards"
icon={<SmartphoneNfcIcon color="gray"/>}/>
-36
View File
@@ -1,36 +0,0 @@
import {ReactNode, useMemo} from "react";
import {Text} from "react-native";
import {CreditCard, History} from "lucide-react-native";
import TimeAgo from "./TimeAgo";
import {AMCardData} from "../models/AMCard";
import {AMUICard, AMUICardActionProps, AMUICardDetail} from "./AMUICard";
export interface AimeCardProps extends AMUICardActionProps {
card: AMCardData,
children?: ReactNode,
showFullCardNumber?: boolean
}
export function AimeCard(props: AimeCardProps) {
const displayedCardNumber = useMemo(() => props.showFullCardNumber
? props.card.code.match(/.{1,4}/g)?.join(" ")
: `•••• ${props.card.code.substring(props.card.code.length - 4)}`,
[props.showFullCardNumber, props.card.code]);
return (
<AMUICard title={props.card.name} {...props}>
<AMUICardDetail>
<CreditCard size={18} color="gray"/>
<Text style={{color: "gray", fontFamily: "JetBrainsMono_400Regular"}}>{displayedCardNumber}</Text>
</AMUICardDetail>
{props.card.lastUsed && (
<AMUICardDetail>
<History size={18} color="gray"/>
<TimeAgo style={{color: "gray"}} dateTo={props.card.lastUsed}/>
</AMUICardDetail>
)}
{props.children}
</AMUICard>
);
}
+83
View File
@@ -0,0 +1,83 @@
import {Text} from "react-native";
import {ReactNode, useMemo} from "react";
import {CreditCard, History, Joystick, Keyboard, KeyRound, Tickets} from "lucide-react-native";
import TimeAgo from "./TimeAgo";
import {AMUICard, AMUICardActionProps, AMUICardDetail} from "./AMUICard";
import {AMCardData, AMPhysicalCardData} from "../models/AMCard";
import {AmusementICVendor, ICType} from "../lib/iccard";
export interface ICCardProps extends AMUICardActionProps {
card: AMCardData,
children?: ReactNode,
showFullCardNumber?: boolean
}
export function ICCard(props: ICCardProps) {
const displayedCardNumber = useMemo(() => props.showFullCardNumber
? props.card.code.match(/.{1,4}/g)?.join(" ")
: `•••• ${props.card.code.substring(props.card.code.length - 4)}`,
[props.showFullCardNumber, props.card.code]);
return (
<AMUICard title={props.card.name} {...props}>
<PhysicalICInfo physicalCard={props.card.physicalCardData}/>
<AMUICardDetail>
<CreditCard size={18} color="gray"/>
<Text style={{color: "gray", fontFamily: "JetBrainsMono_400Regular"}}>{displayedCardNumber}</Text>
</AMUICardDetail>
{props.card.lastUsed && (
<AMUICardDetail>
<History size={18} color="gray"/>
<TimeAgo style={{color: "gray"}} dateTo={props.card.lastUsed}/>
</AMUICardDetail>
)}
{props.children}
</AMUICard>
);
}
function PhysicalICInfo(props: { physicalCard: AMPhysicalCardData | null }) {
if (props.physicalCard?.cardType === ICType.Transport) {
return (
<AMUICardDetail>
<Tickets size={18} color="gray"/>
<Text style={{color: "gray"}}>Transport IC Card</Text>
</AMUICardDetail>
)
}
if (props.physicalCard?.cardVendor) {
return (
<AMUICardDetail>
<Joystick size={18} color="gray"/>
<Text style={{color: "gray"}}>{ICVendorName(props.physicalCard.cardVendor)}</Text>
</AMUICardDetail>
);
}
return null;
}
function ICVendorName(vendor: AmusementICVendor): string {
switch (vendor) {
case AmusementICVendor.Sega:
return "Aime Card";
case AmusementICVendor.Konami:
return "e-Amusement Pass";
case AmusementICVendor.BandaiNamcoGames:
case AmusementICVendor.BandaiNamcoEntertainment:
return "Bana Passport";
case AmusementICVendor.Nesica:
return "Nesica Card";
default:
return "Amusement IC Card";
}
}