mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-25 07:38:17 +03:00
87 lines
2.9 KiB
TypeScript
87 lines
2.9 KiB
TypeScript
import {Text} from "react-native";
|
|
import React, {ReactNode, useMemo} from "react";
|
|
import {CreditCard, Gem, History, Joystick, LucideIcon, RailSymbol} from "lucide-react-native";
|
|
|
|
import TimeAgo from "./TimeAgo";
|
|
import {AMUICard, AMUICardActionProps, AMUICardDetail} from "./AMUICard";
|
|
|
|
import {AmusementICVendor, ICType} from "../lib/iccard";
|
|
import {AMCardData} from "../models/AMCardData";
|
|
|
|
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 card={props.card}/>
|
|
|
|
<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: { card: AMCardData | null }) {
|
|
if (props.card.physicalCardData?.cardType === ICType.Transport) {
|
|
return (
|
|
<AMUICardDetail>
|
|
<RailSymbol size={18} color="gray"/>
|
|
<Text style={{color: "gray"}}>Transport IC Card</Text>
|
|
</AMUICardDetail>
|
|
)
|
|
}
|
|
|
|
if (props.card.physicalCardData?.cardVendor) {
|
|
const [icon, color]: [LucideIcon, string] = props.card.isLimitedAimeCard ? [Gem, "crimson"] : [Joystick, "gray"];
|
|
return (
|
|
<AMUICardDetail>
|
|
{React.createElement(icon, {size: 18, color})}
|
|
<Text style={{color}}>
|
|
{props.card.physicalCardData.isBootlegAmusementCard ? "Bootleg " : null}{ICVendorName(props.card.physicalCardData.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 "Banapass";
|
|
|
|
case AmusementICVendor.Nesica:
|
|
return "NESiCA Card";
|
|
|
|
default:
|
|
return "Amusement IC Card";
|
|
}
|
|
}
|