add card edit support

This commit is contained in:
ppc
2024-09-03 14:52:52 +01:00
parent ef8e03ee9b
commit 15329d5dcd
3 changed files with 67 additions and 31 deletions
+35 -9
View File
@@ -9,7 +9,7 @@ import RealmContext from "../models/RealmContext";
const {useRealm} = RealmContext;
export default function CardAddModal({navigation}) {
export default function CardAddModal({navigation, route}) {
const realm = useRealm();
const theme = useTheme();
const modalStyles = useModalStyles();
@@ -17,9 +17,10 @@ export default function CardAddModal({navigation}) {
// state values
const [cardName, setCardName] = useState('');
const [cardNumber, setCardNumber] = useState('');
const [cardNumberReadOnly, setCardNumberReadOnly] = useState(false);
const cardAddCallback = useCallback((cardId: string, cardName: string) => {
const duplicateCard = realm.objects<AMCard>("card").find(x => x.code == cardNumber);
const duplicateCard = realm.objects<AMCard>("card").find(x => x.code === cardId);
if (duplicateCard) {
realm.write(() => {
@@ -55,6 +56,25 @@ export default function CardAddModal({navigation}) {
})
}, [navigation, modalStyles, cardName, cardNumber]);
// enable renaming by passing cardId to modal
useLayoutEffect(() => {
if (!route.params?.cardId) {
setCardNumberReadOnly(false);
return;
}
setCardNumber(route.params.cardId);
setCardNumberReadOnly(true);
if (route.params.cardName) {
setCardName(route.params.cardName);
}
navigation.setOptions({
title: "Edit Card"
});
}, [route]);
return (<View style={{display: "flex", gap: 10, justifyContent: "center", paddingHorizontal: 15, paddingTop: 25}}>
<Card mode="contained">
<Card.Content>
@@ -76,21 +96,27 @@ export default function CardAddModal({navigation}) {
<Paragraph style={modalStyles.formItemName}>
Matrix Code
</Paragraph>
<TextInput style={modalStyles.formItemInput}
numberOfLines={1}
<TextInput numberOfLines={1}
keyboardType="numeric"
readOnly={cardNumberReadOnly}
placeholder="0000 0000 0000 0000 0000"
placeholderTextColor={theme.colors.outline}
value={cardNumber.match(/.{1,4}/g)?.join(" ")}
onChangeText={val => setCardNumber(val?.replaceAll(/\D/g, '').substring(0, 20) ?? '')}/>
onChangeText={val => setCardNumber(val?.replaceAll(/\D/g, '').substring(0, 20) ?? '')}
style={{...modalStyles.formItemInput, color: cardNumberReadOnly ? theme.colors.backdrop : undefined}}/>
</View>
</Card.Content>
</Card>
<Paragraph style={modalStyles.formFootnote}>
If you have a physical card, you can enter the 20-digit code on the back.
</Paragraph>
{/*only show card entry info when in create mode*/}
{!cardNumberReadOnly && (
<>
<Paragraph style={modalStyles.formFootnote}>
If you have a physical card, you can enter the 20-digit code on the back.
</Paragraph>
<Button mode="text" onPress={() => setCardNumber(generateCardNumber())}>Generate Matrix Code</Button>
<Button mode="text" onPress={() => setCardNumber(generateCardNumber())}>Generate Matrix Code</Button>
</>
)}
</View>)
}
+31 -21
View File
@@ -12,33 +12,42 @@ import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
const {useQuery, useRealm} = RealmContext;
function CardEntry(props: { card: AMCard }) {
function CardEntry(props: { card: AMCard, navigation: any }) {
const realm = useRealm();
const callback = useCallback(async (index: number) => {
const callback = useCallback(async (indexPath: number[]) => {
if (!props.card.isValid()) {
return;
}
switch (index) {
// copy card no
case 0:
switch (indexPath.toString()) {
// copy card
case "0":
await Clipboard.setStringAsync(props.card.code);
break;
case 1:
realm.write(() => {
realm.delete(props.card);
});
break;
return;
// edit card
case "1":
props.navigation.navigate('add-card', {cardId: props.card.code, cardName: props.card.name});
return;
// remove card
case "2,0":
realm.write(() => realm.delete(props.card));
return;
}
}, [realm, props.card]);
}, [realm, props.card, props.navigation]);
return (
<ContextMenu
onPress={e => callback(e.nativeEvent?.index)}
onPress={e => callback(e.nativeEvent?.indexPath)}
actions={[
{title: "Copy Card Number", systemIcon: "doc.on.doc"},
{title: "Delete Card", destructive: true, systemIcon: "trash"}]}>
{title: "Edit Card", systemIcon: "square.and.pencil"},
{
title: "",
inlineChildren: true,
actions: [{title: "Delete Card", destructive: true, systemIcon: "trash"}]
}]}>
<AimeCard card={props.card} showFullCardNumber/>
</ContextMenu>
);
@@ -47,14 +56,15 @@ function CardEntry(props: { card: AMCard }) {
export default function CardManager({navigation}) {
const query = useQuery(AMCard);
const cards = useMemo(() => query.sorted("added", true), [query]);
const theme = useTheme();
if (!cards.length) {
return (
<View style={{flex: 1, gap: 10, justifyContent: "center", alignItems: "center"}}>
<EmptyStatePlaceholder message="No cards added yet" icon={<CreditCard color="gray"/>}/>
<Button mode="text" onPress={() => navigation.navigate('add-card')} icon={() => <Plus size={18} color={theme.colors.primary}/>}>Add Card</Button>
<Button mode="text" onPress={() => navigation.navigate('add-card')}
icon={() => <Plus size={18} color={theme.colors.primary}/>}>Add Card</Button>
</View>
)
}
@@ -66,6 +76,6 @@ export default function CardManager({navigation}) {
keyExtractor={i => i._id.toString()}
contentContainerStyle={{paddingBottom: 40}}
ItemSeparatorComponent={() => <View style={{height: 15}}/>}
renderItem={i => <CardEntry card={i.item}/>}/>
renderItem={i => <CardEntry card={i.item} navigation={navigation}/>}/>
)
}
+1 -1
View File
@@ -4,7 +4,7 @@ import {AMServer} from "./AMServer";
// @ts-ignore
export default createRealmContext({
schemaVersion: 1,
schemaVersion: 2,
schema: [AMCard, AMServer],
deleteRealmIfMigrationNeeded: false
});