mirror of
https://github.com/selfxyz/self.git
synced 2026-02-08 05:15:19 -05:00
clean and remove gluestack dependencies
This commit is contained in:
37
app/App.tsx
37
app/App.tsx
@@ -18,28 +18,10 @@ import {
|
||||
LearnMoreLinks,
|
||||
ReloadInstructions,
|
||||
} from 'react-native/Libraries/NewAppScreen';
|
||||
import {
|
||||
Text,
|
||||
GluestackUIProvider,
|
||||
Checkbox,
|
||||
CheckboxIndicator,
|
||||
CheckboxIcon,
|
||||
CheckIcon,
|
||||
CheckboxLabel,
|
||||
Input,
|
||||
InputField,
|
||||
ButtonText,
|
||||
ButtonIcon,
|
||||
Button,
|
||||
Spinner,
|
||||
View,
|
||||
ButtonSpinner,
|
||||
} from "@gluestack-ui/themed"
|
||||
import { config } from "@gluestack-ui/config" // Optional if you want to use default theme
|
||||
import Toast, { BaseToast, ErrorToast, SuccessToast, ToastProps } from 'react-native-toast-message';
|
||||
// @ts-ignore
|
||||
import PassportReader from 'react-native-passport-reader';
|
||||
import { getFirstName, formatDuration, checkInputs } from './utils/utils';
|
||||
import { checkInputs } from './utils/utils';
|
||||
import {
|
||||
DEFAULT_PNUMBER,
|
||||
DEFAULT_DOB,
|
||||
@@ -72,11 +54,9 @@ import MainScreen from './src/screens/MainScreen';
|
||||
import { extractMRZInfo, Steps } from './src/utils/utils';
|
||||
import forge from 'node-forge';
|
||||
import { Buffer } from 'buffer';
|
||||
import { YStack } from 'tamagui';
|
||||
global.Buffer = Buffer;
|
||||
|
||||
import CustomTextInput from './src/components/CustomTextInput';
|
||||
import EnterDetailsScreen from './src/screens/EnterDetailsScreen';
|
||||
|
||||
console.log('DEFAULT_PNUMBER', DEFAULT_PNUMBER);
|
||||
|
||||
const SKIP_SCAN = false;
|
||||
@@ -103,17 +83,12 @@ function App(): JSX.Element {
|
||||
const [step, setStep] = useState(Steps.MRZ_SCAN);
|
||||
const [testResult, setTestResult] = useState<any>(null);
|
||||
const [error, setError] = useState<any>(null);
|
||||
|
||||
const [generatingProof, setGeneratingProof] = useState<boolean>(false);
|
||||
|
||||
const [proofTime, setProofTime] = useState<number>(0);
|
||||
const [totalTime, setTotalTime] = useState<number>(0);
|
||||
const [proof, setProof] = useState<{ proof: string, inputs: string } | null>(null);
|
||||
const [minting, setMinting] = useState<boolean>(false);
|
||||
const [mintText, setMintText] = useState<string | null>(null);
|
||||
|
||||
|
||||
|
||||
const [disclosure, setDisclosure] = useState({
|
||||
issuing_state: false,
|
||||
name: false,
|
||||
@@ -565,7 +540,7 @@ function App(): JSX.Element {
|
||||
};
|
||||
|
||||
return (
|
||||
<GluestackUIProvider config={config}>
|
||||
<YStack f={1}>
|
||||
<SafeAreaView style={backgroundStyle}>
|
||||
<StatusBar
|
||||
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
||||
@@ -578,7 +553,7 @@ function App(): JSX.Element {
|
||||
}}
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
>
|
||||
<View style={styles.view}>
|
||||
<YStack style={styles.view}>
|
||||
<MainScreen
|
||||
onStartCameraScan={startCameraScan}
|
||||
nfcScan={scan}
|
||||
@@ -603,11 +578,11 @@ function App(): JSX.Element {
|
||||
dateOfExpiry={dateOfExpiry}
|
||||
setDateOfExpiry={setDateOfExpiry}
|
||||
/>
|
||||
</View>
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
<Toast config={toastConfig} />
|
||||
</GluestackUIProvider>
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-private-methods": "^7.23.3",
|
||||
"@ethersproject/shims": "^5.7.0",
|
||||
"@gluestack-style/react": "^1.0.12",
|
||||
"@gluestack-ui/config": "^1.0.3",
|
||||
"@gluestack-ui/themed": "^1.0.11",
|
||||
"@tamagui/config": "^1.84.0",
|
||||
"@tamagui/lucide-icons": "^1.84.0",
|
||||
"axios": "^1.6.3",
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Text, YStack, XStack, Card, H3, Image } from 'tamagui';
|
||||
import { ChevronRight } from '@tamagui/lucide-icons';
|
||||
|
||||
const MyCard = ({ title, description, colorOfTheText, background, id, onTouchStart, eleva }) => {
|
||||
const AppCard = ({ title, description, colorOfTheText, background, id, onTouchStart, eleva }) => {
|
||||
return (
|
||||
<Card
|
||||
key={id}
|
||||
@@ -38,4 +38,4 @@ const MyCard = ({ title, description, colorOfTheText, background, id, onTouchSta
|
||||
);
|
||||
}
|
||||
|
||||
export default MyCard;
|
||||
export default AppCard;
|
||||
@@ -1,40 +0,0 @@
|
||||
// src/components/Button.tsx
|
||||
|
||||
import React from 'react';
|
||||
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
|
||||
|
||||
const CustomButton = ({ onPress, title }) => {
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress} style={[styles.button]}>
|
||||
<Text style={styles.text}>{title}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
backgroundColor: '#007bff', // A blue color
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 20,
|
||||
borderRadius: 25, // Rounded corners
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
elevation: 2, // Android shadow
|
||||
shadowOpacity: 0.25, // iOS shadow
|
||||
shadowRadius: 3.84,
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
marginTop: 20, // Add some margin at the top
|
||||
width: '90%', // Set width to 90% of the container
|
||||
alignSelf: 'center', // Center the TextInput in its container
|
||||
},
|
||||
text: {
|
||||
color: 'white',
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
||||
export default CustomButton;
|
||||
@@ -1,34 +0,0 @@
|
||||
// src/components/CustomTextInput.tsx
|
||||
|
||||
import React from 'react';
|
||||
import { TextInput, StyleSheet } from 'react-native';
|
||||
|
||||
const CustomTextInput = ({ value, onChangeText, placeholder, keyboardType }) => {
|
||||
return (
|
||||
<TextInput
|
||||
value={value}
|
||||
onChangeText={onChangeText}
|
||||
placeholder={placeholder}
|
||||
placeholderTextColor="gray" // Set the placeholder text color to gray
|
||||
autoCapitalize="characters"
|
||||
keyboardType={keyboardType}
|
||||
style={styles.input}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
input: {
|
||||
borderColor: 'gray',
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
padding: 10,
|
||||
marginVertical: 8,
|
||||
color: 'black', // Set the input text color to black
|
||||
backgroundColor: 'white', // Ensure the background is white if not already set
|
||||
width: '90%', // Set width to 90% of the container
|
||||
alignSelf: 'center', // Center the TextInput in its container
|
||||
},
|
||||
});
|
||||
|
||||
export default CustomTextInput;
|
||||
@@ -1,50 +0,0 @@
|
||||
// src/components/ToggleButton.tsx
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
|
||||
|
||||
const ToggleButton = ({ onToggle, initialState = false, titles = ['Off', 'On'] }) => {
|
||||
const [isToggled, setIsToggled] = useState(initialState);
|
||||
|
||||
const handlePress = () => {
|
||||
const newState = !isToggled;
|
||||
setIsToggled(newState);
|
||||
if (onToggle) {
|
||||
onToggle(newState);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={handlePress}
|
||||
style={[styles.button, isToggled ? styles.toggled : styles.notToggled]}
|
||||
>
|
||||
<Text style={styles.text}>{isToggled ? titles[1] : titles[0]}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 20,
|
||||
borderRadius: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
elevation: 2,
|
||||
marginVertical: 10,
|
||||
},
|
||||
toggled: {
|
||||
backgroundColor: 'blue',
|
||||
},
|
||||
notToggled: {
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
text: {
|
||||
color: 'white',
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
||||
export default ToggleButton;
|
||||
BIN
app/src/images/user.png
Normal file
BIN
app/src/images/user.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 241 KiB |
@@ -1,9 +1,8 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import ZUPASS from '../images/zupass.png';
|
||||
import GITCOIN from '../images/gitcoin.png';
|
||||
import { Text, YStack, Card, H2, H3, Paragraph, Image, Button, XStack, CardFooter } from 'tamagui';
|
||||
import { ChevronRight, X } from '@tamagui/lucide-icons';
|
||||
import MyCard from '../components/MyCard';
|
||||
import { YStack } from 'tamagui';
|
||||
import AppCard from '../components/AppCard';
|
||||
import { App, gitcoin, soulbond, zuzalu } from '../utils/AppClass';
|
||||
const AppScreen = ({ selectedApp, setSelectedApp }) => {
|
||||
|
||||
@@ -38,7 +37,7 @@ const AppScreen = ({ selectedApp, setSelectedApp }) => {
|
||||
<YStack gap="$5" w="100%" p="$5">
|
||||
|
||||
{cardsData.map(card => (
|
||||
<MyCard
|
||||
<AppCard
|
||||
key={card.app.id}
|
||||
title={card.title}
|
||||
description={card.description}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
// src/screens/EnterDetailsScreen.tsx
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import CustomTextInput from '../components/CustomTextInput';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import { ToggleGroup } from 'tamagui'
|
||||
import { AlignCenter, AlignLeft, AlignRight, Camera } from '@tamagui/lucide-icons'
|
||||
import { SizableText, Tabs, H5 } from 'tamagui'
|
||||
import { XStack, YStack, Button } from 'tamagui'
|
||||
|
||||
const EnterDetailsScreen = ({
|
||||
passportNumber,
|
||||
setPassportNumber,
|
||||
dateOfBirth,
|
||||
setDateOfBirth,
|
||||
dateOfExpiry,
|
||||
setDateOfExpiry,
|
||||
onScanPress,
|
||||
onStartCameraScan
|
||||
}) => {
|
||||
const [selectedToggle, setSelectedToggle] = useState('camera');
|
||||
const handleCameraPress = () => {
|
||||
onStartCameraScan();
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.header}>Welcome to Proof of Passport</Text>
|
||||
<Text style={styles.header2}>Generate ZK proof with your passport data</Text>
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
value={selectedToggle}
|
||||
onValueChange={setSelectedToggle}
|
||||
disableDeactivation={true}
|
||||
sizeAdjust={1}
|
||||
>
|
||||
<ToggleGroup.Item value="camera" onPress={handleCameraPress}>
|
||||
<Camera />
|
||||
</ToggleGroup.Item>
|
||||
</ToggleGroup>
|
||||
|
||||
{true ? (
|
||||
<View style={styles.inputContainer}>
|
||||
<CustomTextInput
|
||||
value={passportNumber}
|
||||
onChangeText={setPassportNumber}
|
||||
placeholder="Passport number"
|
||||
keyboardType="default"
|
||||
/>
|
||||
<CustomTextInput
|
||||
value={dateOfBirth}
|
||||
onChangeText={setDateOfBirth}
|
||||
placeholder="Date of birth (yymmdd)"
|
||||
keyboardType="numeric"
|
||||
/>
|
||||
<CustomTextInput
|
||||
value={dateOfExpiry}
|
||||
onChangeText={setDateOfExpiry}
|
||||
placeholder="Date of expiry (yymmdd)"
|
||||
keyboardType="numeric"
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.header2}>Work in progress</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<Button onPress={onScanPress} title="Scan Passport with NFC" />
|
||||
|
||||
|
||||
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
sectionContainer: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 24,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white',
|
||||
paddingBottom: 20,
|
||||
},
|
||||
header: {
|
||||
fontSize: 22,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
marginTop: 40,
|
||||
color: 'black',
|
||||
},
|
||||
header2: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
marginTop: 20,
|
||||
marginBottom: 20,
|
||||
color: 'gray',
|
||||
},
|
||||
inputContainer: {
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default EnterDetailsScreen;
|
||||
@@ -5,7 +5,7 @@ import ScanScreen from './ScanScreen';
|
||||
import ProveScreen from './ProveScreen';
|
||||
import { Steps } from '../utils/utils';
|
||||
import AppScreen from './AppScreen';
|
||||
import { App, gitcoin, soulbond, zuzalu } from '../utils/AppClass';
|
||||
import { App } from '../utils/AppClass';
|
||||
const MainScreen = (
|
||||
{ onStartCameraScan,
|
||||
nfcScan,
|
||||
@@ -35,7 +35,7 @@ const MainScreen = (
|
||||
const [selectedApp, setSelectedApp] = useState<App | null>(null);
|
||||
const [brokenCamera, setBrokenCamera] = useState(false);
|
||||
const [open, setOpen] = useState(false)
|
||||
const MyCard = styled(ThemeableStack, {
|
||||
const AppCard = styled(ThemeableStack, {
|
||||
hoverTheme: true,
|
||||
pressTheme: true,
|
||||
focusTheme: true,
|
||||
@@ -193,8 +193,8 @@ const MainScreen = (
|
||||
|
||||
|
||||
<Tabs f={1} defaultValue="scan" orientation='horizontal' dir='ltr' shadowColor="black" onValueChange={(newValue) => setSelectedTab(newValue)}>
|
||||
<YStack f={1} ai="center" jc="space-between" >
|
||||
<XStack />
|
||||
<YStack ai="center" jc="space-between" bc="" >
|
||||
<XStack flexGrow={0} ai="center" />
|
||||
|
||||
<Tabs.Content value="scan">
|
||||
<ScanScreen
|
||||
@@ -275,8 +275,8 @@ const MainScreen = (
|
||||
</Tabs.List>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</Tabs>
|
||||
</YStack>
|
||||
</Tabs >
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack, Text, Checkbox, Input, Button, Spinner, SizableText } from 'tamagui';
|
||||
import { YStack, XStack, Text, Checkbox, Input, Button, Spinner, SizableText, Image } from 'tamagui';
|
||||
import { Check } from '@tamagui/lucide-icons';
|
||||
import { getFirstName, formatDuration } from '../../utils/utils';
|
||||
import { attributeToPosition } from '../../../common/src/constants/constants';
|
||||
import { Steps } from '../utils/utils';
|
||||
import USER from '../images/user.png'
|
||||
|
||||
const ProveScreen = ({
|
||||
passportData,
|
||||
@@ -24,77 +25,90 @@ const ProveScreen = ({
|
||||
}) => {
|
||||
return (
|
||||
<YStack space="$4" p="$4" >
|
||||
{step < Steps.PROOF_GENERATED ? (
|
||||
<YStack>
|
||||
<YStack my="$4">
|
||||
<SizableText mb="$1">Hi {getFirstName(passportData.mrz)},</SizableText>
|
||||
<Text mb="$2">{selectedApp.name} Is asking for the following information</Text>
|
||||
{Object.keys(selectedApp.disclosure).map((key) => {
|
||||
const keyy = key as keyof typeof disclosure;
|
||||
const indexes = attributeToPosition[keyy];
|
||||
const keyFormatted = keyy.replace(/_/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
||||
const mrzAttribute = passportData.mrz.slice(indexes[0], indexes[1]);
|
||||
const mrzAttributeFormatted = mrzAttribute.replace(/</g, ' ');
|
||||
{
|
||||
step < Steps.PROOF_GENERATED ? (
|
||||
<YStack >
|
||||
<YStack w="100%" ai="center">
|
||||
<Image
|
||||
w="$12"
|
||||
h="$12"
|
||||
flex={1}
|
||||
borderRadius="$10"
|
||||
source={{
|
||||
uri: USER
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
<YStack mt="$12">
|
||||
<SizableText mb="$1">Hi {getFirstName(passportData.mrz)},</SizableText>
|
||||
<Text mb="$2">{selectedApp.name} is asking for the following information:</Text>
|
||||
{Object.keys(selectedApp.disclosure).map((key) => {
|
||||
const keyy = key as keyof typeof disclosure;
|
||||
const indexes = attributeToPosition[keyy];
|
||||
const keyFormatted = keyy.replace(/_/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
||||
const mrzAttribute = passportData.mrz.slice(indexes[0], indexes[1]);
|
||||
const mrzAttributeFormatted = mrzAttribute.replace(/</g, ' ');
|
||||
|
||||
return (
|
||||
<XStack key={key} m="$2" w="$full" gap="$2">
|
||||
return (
|
||||
<XStack key={key} m="$2" w="$full" gap="$2">
|
||||
|
||||
<Checkbox
|
||||
value={key}
|
||||
checked={disclosure[keyy]}
|
||||
onCheckedChange={() => handleDisclosureChange(keyy)}
|
||||
aria-label={keyFormatted}
|
||||
size="$5"
|
||||
>
|
||||
<Checkbox.Indicator >
|
||||
<Check />
|
||||
</Checkbox.Indicator>
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
value={key}
|
||||
checked={disclosure[keyy]}
|
||||
onCheckedChange={() => handleDisclosureChange(keyy)}
|
||||
aria-label={keyFormatted}
|
||||
size="$5"
|
||||
>
|
||||
<Checkbox.Indicator >
|
||||
<Check />
|
||||
</Checkbox.Indicator>
|
||||
</Checkbox>
|
||||
|
||||
<Text fontWeight="bold">{keyFormatted}: </Text>
|
||||
<Text>{mrzAttributeFormatted}</Text>
|
||||
<Text fontWeight="bold">{keyFormatted}: </Text>
|
||||
<Text>{mrzAttributeFormatted}</Text>
|
||||
</XStack>
|
||||
);
|
||||
})}
|
||||
</YStack>
|
||||
<Text mt="$3">Enter your address or ens</Text>
|
||||
<Input
|
||||
size="md"
|
||||
mt="$3"
|
||||
placeholder="Your Address or ens name"
|
||||
value={address}
|
||||
onChangeText={setAddress}
|
||||
/>
|
||||
|
||||
<Button borderRadius={100} onPress={handleProve} mt="$6" backgroundColor="#cececece" >
|
||||
{generatingProof ? (
|
||||
<XStack ai="center">
|
||||
<Spinner />
|
||||
<Text color="white" marginLeft="$2" fow="bold">Generating zk proof</Text>
|
||||
</XStack>
|
||||
);
|
||||
})}
|
||||
) : (
|
||||
<Text color="white" fow="bold">Generate zk proof</Text>
|
||||
)}
|
||||
</Button>
|
||||
</YStack>
|
||||
<Text mt="$3">Enter your address or ens</Text>
|
||||
<Input
|
||||
size="md"
|
||||
mt="$3"
|
||||
placeholder="Your Address or ens name"
|
||||
value={address}
|
||||
onChangeText={setAddress}
|
||||
/>
|
||||
) : (
|
||||
<YStack m="$2">
|
||||
<Text>Zero-knowledge proof generated</Text>
|
||||
|
||||
<Button borderRadius={100} onPress={handleProve} mt="$6" backgroundColor="#cececece" >
|
||||
{generatingProof ? (
|
||||
<XStack ai="center">
|
||||
<Spinner />
|
||||
<Text color="white" marginLeft="$2" fow="bold">Generating zk proof</Text>
|
||||
</XStack>
|
||||
) : (
|
||||
<Text color="white" fow="bold">Generate zk proof</Text>
|
||||
)}
|
||||
</Button>
|
||||
</YStack>
|
||||
) : (
|
||||
<YStack m="$2">
|
||||
<Text>Zero-knowledge proof generated</Text>
|
||||
<Text fontWeight="bold">Proof:</Text>
|
||||
<Text>{JSON.stringify(proof)}</Text>
|
||||
|
||||
<Text fontWeight="bold">Proof:</Text>
|
||||
<Text>{JSON.stringify(proof)}</Text>
|
||||
<Text fontWeight="bold">Proof Duration: {formatDuration(proofTime)}</Text>
|
||||
<Text fontWeight="bold">Total Duration: {formatDuration(totalTime)}</Text>
|
||||
|
||||
<Text fontWeight="bold">Proof Duration: {formatDuration(proofTime)}</Text>
|
||||
<Text fontWeight="bold">Total Duration: {formatDuration(totalTime)}</Text>
|
||||
<Button borderRadius={100} onPress={handleMint} marginTop="$4" mb="$4" backgroundColor="#3185FC">
|
||||
<Text color="white" fow="bold">Mint Proof of Passport</Text>
|
||||
</Button>
|
||||
|
||||
<Button borderRadius={100} onPress={handleMint} marginTop="$4" mb="$4" backgroundColor="#3185FC">
|
||||
<Text color="white" fow="bold">Mint Proof of Passport</Text>
|
||||
</Button>
|
||||
|
||||
{mintText && <Text>{mintText}</Text>}
|
||||
</YStack>
|
||||
)}
|
||||
</YStack>
|
||||
{mintText && <Text>{mintText}</Text>}
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
export default ProveScreen;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { YStack, Text, Spinner, Circle, ZStack, XStack, SizableText } from 'tamagui'; // Ensure correct import paths based on your project setup
|
||||
import { Steps } from '../utils/utils';
|
||||
const ScanScreen = ({ onStartCameraScan, nfcScan, step }) => {
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<YStack >
|
||||
<ZStack alignSelf='center' maxWidth={50} maxHeight={50} width={50} flex={1} space="$0">
|
||||
|
||||
1363
app/yarn.lock
1363
app/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user