Add nested xml

This commit is contained in:
abhay-raizada
2024-05-27 02:24:33 +05:30
parent 46bde49497
commit 6720585cf5
9 changed files with 458 additions and 245 deletions

19
App.tsx
View File

@@ -5,14 +5,14 @@
* @format
*/
import React, { useEffect, useState } from 'react';
import { SafeAreaView, ScrollView, StatusBar, StyleSheet } from 'react-native';
import React, {useEffect, useState} from 'react';
import {SafeAreaView, ScrollView, StatusBar, StyleSheet} from 'react-native';
import { getFormTemplate } from './formstr/formstr';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import { PrescriptionCreator } from './components/PrescriptionCreator';
import {getFormTemplate} from './formstr/formstr';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {PrescriptionCreator} from './components/PrescriptionCreator';
import 'react-native-url-polyfill/auto';
import PolyfillCrypto from 'react-native-webview-crypto'
import PolyfillCrypto from 'react-native-webview-crypto';
function App(): React.JSX.Element {
const backgroundStyle = {
@@ -27,12 +27,11 @@ function App(): React.JSX.Element {
if (!form) {
let form = await getFormTemplate(
'eb3df1f89653475f0bcbd22da35f8d2f126db8a68a88a7abedc53535c76c39b4',
)
setForm(form);
);
}
};
fetchForm();
}, [form]);
}, [form, setForm]);
return (
<SafeAreaView style={backgroundStyle}>
@@ -44,7 +43,7 @@ function App(): React.JSX.Element {
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<PrescriptionCreator form={form}/>
<PrescriptionCreator />
</ScrollView>
</SafeAreaView>
);

View File

@@ -1,7 +1,15 @@
import { DatePicker, DatePickerView, InputItem, List, Text, TextareaItem, View } from "@ant-design/react-native";
import { V1AnswerSettings, AnswerTypes } from "@formstr/sdk/dist/interfaces";
import { useState } from "react";
import RNPickerSelect from "react-native-picker-select"
import {
DatePicker,
DatePickerView,
InputItem,
List,
Text,
TextareaItem,
View,
} from '@ant-design/react-native';
import {V1AnswerSettings, AnswerTypes} from '@formstr/sdk/dist/interfaces';
import {useState} from 'react';
import RNPickerSelect from 'react-native-picker-select';
interface InputFillerProps {
answerType: AnswerTypes;
@@ -16,39 +24,38 @@ export const InputFiller: React.FC<InputFillerProps> = ({
onChange,
defaultValue,
}) => {
const [inputValue, setInputValue] = useState("");
const handleInputChange = (
e: any
) => {
console.log("E is", e)
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e: any) => {
console.log('E is', e);
setInputValue(e);
onChange(e)
onChange(e);
};
const handleValueChange = (value: string) => {
if (!value) return;
setInputValue(value)
setInputValue(value);
onChange(value);
};
const getInput = (
answerType: AnswerTypes,
answerSettings: V1AnswerSettings
answerSettings: V1AnswerSettings,
) => {
const dropdownItems = (answerSettings.choices || []).map((choice) => {
const dropdownItems = (answerSettings.choices || []).map(choice => {
return {
label: choice.label, value: choice.choiceId, key: choice.choiceId
}})
const INPUT_TYPE_COMPONENT_MAP: { [key in AnswerTypes]?: JSX.Element } = {
label: choice.label,
value: choice.choiceId,
key: choice.choiceId,
};
});
const INPUT_TYPE_COMPONENT_MAP: {[key in AnswerTypes]?: JSX.Element} = {
[AnswerTypes.label]: <></>,
[AnswerTypes.shortText]: (
<InputItem
onChange={handleValueChange}
defaultValue={defaultValue as string}
placeholder="enter a value..."
placeholderTextColor="#aaaaaa">
</InputItem>
placeholderTextColor="#aaaaaa"></InputItem>
),
[AnswerTypes.paragraph]: (
<TextareaItem
@@ -57,53 +64,36 @@ export const InputFiller: React.FC<InputFillerProps> = ({
placeholderTextColor="#aaaaaa"
onChange={handleInputChange}
autoHeight
style={{ paddingVertical: 5 }}
style={{paddingVertical: 5}}
/>
),
[AnswerTypes.number]: (
// <InputNumber
// defaultValue={defaultValue as string}
// onChange={handleValueChange}
// style={{ width: "100%" }}
// placeholder="Please enter your response"
// />
<View></View>
),
[AnswerTypes.radioButton]: (
// <ChoiceFiller
// answerType={answerType as AnswerTypes.radioButton}
// answerSettings={answerSettings}
// defaultValue={defaultValue as string}
// onChange={handleValueChange}
// />
<View></View>
),
[AnswerTypes.checkboxes]: (
// <ChoiceFiller
// defaultValue={defaultValue as string}
// answerType={answerType as AnswerTypes.checkboxes}
// answerSettings={answerSettings}
// onChange={handleValueChange}
// />
<View></View>
),
[AnswerTypes.number]: <View></View>,
[AnswerTypes.radioButton]: <View></View>,
[AnswerTypes.checkboxes]: <View></View>,
[AnswerTypes.dropdown]: (
<RNPickerSelect
onValueChange={handleValueChange}
items={dropdownItems}
placeholder={{}}
key="picker"
value={inputValue}
><Text>{inputValue ? answerSettings.choices?.filter((choice) => { return choice.choiceId === inputValue})[0].label : "Select an option"}</Text></RNPickerSelect>
<RNPickerSelect
onValueChange={handleValueChange}
items={dropdownItems}
placeholder={{}}
key="picker"
value={inputValue}>
<Text>
{inputValue
? answerSettings.choices?.filter(choice => {
return choice.choiceId === inputValue;
})[0].label
: 'Select an option'}
</Text>
</RNPickerSelect>
),
[AnswerTypes.date]: (
<List>
<DatePicker key="Datepicker" />
<DatePicker key="Datepicker" />
</List>
),
[AnswerTypes.time]: (
<List>
<DatePicker key="time" />
<DatePicker key="time" />
</List>
),
};

View File

@@ -0,0 +1,51 @@
import {Text, TextInput, View} from 'react-native';
import {Section} from './Section';
import {styles, TextTheme} from './styles';
import {useState} from 'react';
import DatePicker from 'react-native-date-picker';
import {Button} from '@ant-design/react-native';
interface AddressForm {
address_line_1?: string;
city?: string;
state_province?: string;
postal_code?: string;
country_code?: string;
}
interface AddressFormProps {
nestedFormCallback: (tag: string, form: Object) => void;
}
export const AddressForm: React.FC<AddressFormProps> = ({
nestedFormCallback,
}) => {
const [form, setForm] = useState<AddressForm>({});
const [openDate, setOpenDate] = useState<boolean>(false);
const handleTextChange = (tag: keyof AddressForm, text: string) => {
let newForm = {...form};
newForm[tag] = text;
setForm(newForm);
nestedFormCallback('Address', newForm);
};
return (
<Section title="Address">
<View>
<View>
<Text style={TextTheme}>Name</Text>
<TextInput
style={styles.input}
placeholder="Address Line 1"
value={form.address_line_1}
placeholderTextColor="white"
onChangeText={(text: string) =>
handleTextChange('address_line_1', text)
}
/>
</View>
</View>
</Section>
);
};

View File

@@ -0,0 +1,80 @@
import {Text, TextInput, View} from 'react-native';
import {Section} from './Section';
import {styles, TextTheme} from './styles';
import {useState} from 'react';
import DatePicker from 'react-native-date-picker';
import {Button} from '@ant-design/react-native';
interface PatientForm {
name?: string;
date_of_birth?: string;
}
interface PatientFormProps {
nestedFormCallback: (tag: string, form: Object) => void;
}
export const PatientForm: React.FC<PatientFormProps> = ({
nestedFormCallback,
}) => {
const [form, setForm] = useState<PatientForm>({});
const [openDate, setOpenDate] = useState<boolean>(false);
const handleTextChange = (tag: 'name' | 'date_of_birth', text: string) => {
let newForm = {...form};
newForm[tag] = text;
setForm(newForm);
nestedFormCallback('patient', {human_patient: newForm});
};
return (
<Section title="Patient">
<View>
<View>
<Text style={TextTheme}>Name</Text>
<TextInput
style={styles.input}
placeholder="Enter Patients Name"
value={form.name}
placeholderTextColor="white"
onChangeText={(text: string) => handleTextChange('name', text)}
/>
</View>
<View>
<Text style={TextTheme}>Date of Birth</Text>
{form.date_of_birth ? (
<View>
<Text style={TextTheme}>{form.date_of_birth}</Text>
<Button
size="small"
onPress={() => {
setOpenDate(true);
}}>
Edit
</Button>
</View>
) : (
<Button
onPress={() => {
setOpenDate(true);
}}
size="small">
Pick a date
</Button>
)}
<DatePicker
modal
mode={'date'}
open={openDate}
date={new Date(form.date_of_birth || '01-01-1990')}
onCancel={() => setOpenDate(false)}
onConfirm={(date: Date) => {
handleTextChange('date_of_birth', date.toDateString());
setOpenDate(false);
}}
/>
</View>
</View>
</Section>
);
};

View File

@@ -0,0 +1,17 @@
import {PropsWithChildren} from 'react';
import {Dimensions, StyleSheet, Text, View} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {styles} from './styles';
type SectionProps = PropsWithChildren<{
title: string;
}>;
export function Section({children, title}: SectionProps): React.JSX.Element {
return (
<View style={styles.sectionContainer}>
<Text style={styles.sectionTitle}>{title}</Text>
<Text style={[styles.sectionDescription]}>{children}</Text>
</View>
);
}

View File

@@ -1,192 +1,213 @@
import { Alert, Appearance, Dimensions, Image, StyleSheet, Text, View } from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import { PropsWithChildren, useEffect, useState } from 'react';
import { Button, Card, Modal } from '@ant-design/react-native';
import { V1Field } from '@formstr/sdk/dist/interfaces';
import { InputFiller } from '../Inputs/Inputs';
import {Alert, Appearance, Dimensions, Image, Text, View} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {PropsWithChildren, useEffect, useState} from 'react';
import {Button, Card, Modal} from '@ant-design/react-native';
// import { SendPrescription } from './sendPrescription';
import { Dropdown } from 'react-native-element-dropdown';
import { SimplePool, UnsignedEvent, finalizeEvent, generateSecretKey, getPublicKey, nip04, nip19 } from 'nostr-tools';
import {Dropdown} from 'react-native-element-dropdown';
import {
SimplePool,
UnsignedEvent,
finalizeEvent,
generateSecretKey,
getPublicKey,
nip04,
nip19,
} from 'nostr-tools';
import EncryptedStorage from 'react-native-encrypted-storage';
import { ImportNsec } from './ImportNsec';
import { json2xml } from 'xml-js';
import {ImportNsec} from './ImportNsec';
import {json2xml} from 'xml-js';
import {Section} from './Section';
import {PatientForm} from './PatientForm';
import {AddressForm} from './AddressForm';
/*
Patient
- Name
- Date Of Birth
Address
- Address Line 1
- City
- StateProvince
- Postal Code
- Country Code
Medicine
- Name
- Dosage Form
- Strength
- Quantity
- Re-fills
- Directions
`
*/
function OBJtoXML(obj: any) {
var xml = '';
for (var prop in obj) {
xml += "<" + prop + ">";
if(Array.isArray(obj[prop])) {
for (var array of obj[prop]) {
xml += '<' + prop + '>';
if (Array.isArray(obj[prop])) {
for (var array of obj[prop]) {
// A real botch fix here
xml += '</' + prop + '>';
xml += '<' + prop + '>';
// A real botch fix here
xml += "</" + prop + ">";
xml += "<" + prop + ">";
xml += OBJtoXML(new Object(array));
}
} else if (typeof obj[prop] == "object") {
xml += OBJtoXML(new Object(obj[prop]));
} else {
xml += obj[prop];
xml += OBJtoXML(new Object(array));
}
xml += "</" + prop + ">";
} else if (typeof obj[prop] == 'object') {
xml += OBJtoXML(new Object(obj[prop]));
} else {
xml += obj[prop];
}
xml += '</' + prop + '>';
}
var xml = xml.replace(/<\/?[0-9]{1,}>/g,'');
return xml
var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
return xml;
}
type SectionProps = PropsWithChildren<{
title: string;
}>;
const colorScheme = Appearance.getColorScheme();
const backgroundStyle = {
backgroundColor: Colors.darker,
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
width: Dimensions.get('window').width - 80,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '500',
},
});
const width = Dimensions.get('window').width; //full width
const height = Dimensions.get('window').height
const height = Dimensions.get('window').height;
function Section({ children, title }: SectionProps): React.JSX.Element {
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: Colors.white,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: Colors.light,
},
]}>
{children}
</Text>
</View>
);
}
const locationData = [
{ label: 'Pharmacy A', value: 'A', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://relay.damus.io"] },
{ label: 'Pharmacy B', value: 'B', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://relay.primal.net"] },
{ label: 'Pharmacy C', value: 'C', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://relay.hllo.live"] },
{ label: 'Pharmacy D', value: 'D', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://nos.lol", "wss://relay.damus.io"] }
]
{
label: 'Pharmacy A',
value: 'A',
npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km',
relays: ['wss://relay.damus.io'],
},
{
label: 'Pharmacy B',
value: 'B',
npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km',
relays: ['wss://relay.primal.net'],
},
{
label: 'Pharmacy C',
value: 'C',
npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km',
relays: ['wss://relay.hllo.live'],
},
{
label: 'Pharmacy D',
value: 'D',
npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km',
relays: ['wss://nos.lol', 'wss://relay.damus.io'],
},
];
const locationDummyData = [
{ label: 'Pharmacy A', value: 'A' }
]
const locationDummyData = [{label: 'Pharmacy A', value: 'A'}];
export const PrescriptionCreator = ({ form }: { form: any }) => {
if (form === null) return <View style={{ backgroundColor: "#ffffff" }}><Text style={{ color: "#000000" }}>Loading...</Text></View>
export const PrescriptionCreator = () => {
const [showImportNsec, setShowImportNsec] = useState(false);
const [loggedInNpub, setLoggedInNpub] = useState("")
const [selectedPharmacyId, setSelectedPharmacyId] = useState(locationData[0].npub);
const [loggedInNpub, setLoggedInNpub] = useState('');
const [selectedPharmacyId, setSelectedPharmacyId] = useState(
locationData[0].npub,
);
const [selectedPharmacyRelays, setSelectedPharmacyRelays] = useState([]);
const [finalJSON, setFinalJson] = useState({})
const [finalJSON, setFinalJson] = useState({});
useEffect(() => {
async function initialize() {
let doctorCredentials = null;
try {
doctorCredentials = await EncryptedStorage.getItem("user_credentials");
if(!doctorCredentials) {
setShowImportNsec(true)
doctorCredentials = await EncryptedStorage.getItem('user_credentials');
if (!doctorCredentials) {
setShowImportNsec(true);
} else {
setLoggedInNpub(
nip19.npubEncode(
getPublicKey(nip19.decode(doctorCredentials).data as Uint8Array),
),
);
}
else {
setLoggedInNpub(nip19.npubEncode(getPublicKey(nip19.decode(doctorCredentials).data as Uint8Array)))
}
}
catch(e) {
console.log("Error getting credentials", e)
} catch (e) {
console.log('Error getting credentials', e);
}
}
initialize()
}, [])
initialize();
}, []);
const renderItem = (item: any) => {
return <View style={{ width: width, display: 'flex', flexDirection: 'column', padding: 10, flexWrap: "wrap" }}>
<Text style={{ color: "black", fontSize: 24 }}>{item.label}</Text>
<View style={{ width: width - 100 }}>
<Text style={{ color: 'grey', paddingBottom: 5 }}>Npub: {item.npub}</Text>
<Text style={{ color: 'grey' }}>Relays: {item.relays.join(', ')}</Text>
return (
<View
style={{
width: width,
display: 'flex',
flexDirection: 'column',
padding: 10,
flexWrap: 'wrap',
}}>
<Text style={{color: 'black', fontSize: 24}}>{item.label}</Text>
<View style={{width: width - 100}}>
<Text style={{color: 'grey', paddingBottom: 5}}>
Npub: {item.npub}
</Text>
<Text style={{color: 'grey'}}>Relays: {item.relays.join(', ')}</Text>
</View>
</View>
</View>
}
);
};
const handleFormItemChange = (questionId: string, value: string) => {
console.log("Filling", questionId, value)
setFinalJson({...finalJSON, [questionId]: value})
}
const nestedFormCallback = (
xmlTag: string,
value: Object | Array<any> | string,
) => {
console.log('Filling', xmlTag, value);
setFinalJson({...finalJSON, [xmlTag]: value});
};
const handleLocationChange = (item: any) => {
setSelectedPharmacyId(item.npub)
setSelectedPharmacyRelays(item.relays)
}
setSelectedPharmacyId(item.npub);
setSelectedPharmacyRelays(item.relays);
};
const handleImportNsec = (nsec: string) => {
EncryptedStorage.setItem("user_credentials", nsec)
if(nsec.startsWith('nsec1') && nsec.length !== 63) {
Alert.alert("not a valid nsec!")
EncryptedStorage.setItem('user_credentials', nsec);
if (nsec.startsWith('nsec1') && nsec.length !== 63) {
Alert.alert('not a valid nsec!');
return;
}
setLoggedInNpub(nip19.npubEncode(getPublicKey(nip19.decode(nsec).data as Uint8Array)))
setShowImportNsec(false)
}
setLoggedInNpub(
nip19.npubEncode(getPublicKey(nip19.decode(nsec).data as Uint8Array)),
);
setShowImportNsec(false);
};
const handleButtonPress = () => {
console.log("Final JSON is", finalJSON)
const xml = OBJtoXML({form: finalJSON })
console.log("XML is...", xml, typeof xml )
console.log('Final JSON is', finalJSON);
const xml = OBJtoXML({prescription: finalJSON});
console.log('XML is...', xml, typeof xml);
sendPrescription(xml);
}
};
const sendPrescription = async (xml: string) => {
console.log("Will generate IDs")
const sk = nip19.decode(await EncryptedStorage.getItem("user_credentials") as `nsec1${string}`).data as Uint8Array
const pk = getPublicKey(sk)
const pharmacyId = nip19.decode(selectedPharmacyId).data as string
console.log("Got ids")
console.log('Will generate IDs');
const sk = nip19.decode(
(await EncryptedStorage.getItem('user_credentials')) as `nsec1${string}`,
).data as Uint8Array;
const pk = getPublicKey(sk);
const pharmacyId = nip19.decode(selectedPharmacyId).data as string;
console.log('Got ids');
console.log('content is ', xml);
const baseKind4Event: UnsignedEvent = {
kind: 4,
tags: [["p", pharmacyId]],
content: await nip04.encrypt(sk, pharmacyId, `This is a test prescription from PeerScribe ${xml}`),
tags: [['p', pharmacyId]],
content: await nip04.encrypt(sk, pharmacyId, `${xml}`),
created_at: Math.floor(Date.now() / 1000),
pubkey: pk
}
const finalEvent = finalizeEvent(baseKind4Event, sk)
const pool = new SimplePool()
console.log("publishing event")
await Promise.any(pool.publish(selectedPharmacyRelays, finalEvent))
console.log("Event Published")
Alert.alert("Prescription Sent to the pharmacy!")
}
pubkey: pk,
};
const finalEvent = finalizeEvent(baseKind4Event, sk);
const pool = new SimplePool();
console.log('publishing event');
await Promise.any(pool.publish(selectedPharmacyRelays, finalEvent));
console.log('Event Published');
Alert.alert('Prescription Sent to the pharmacy!');
};
return (
<View
@@ -199,58 +220,60 @@ export const PrescriptionCreator = ({ form }: { form: any }) => {
width: Dimensions.get('window').width,
}}
source={{
uri: form.settings.titleImageUrl,
uri: 'https://www.studentdoctor.net/wp-content/uploads/2018/08/20180815_prescription.png',
}}
/>
<Section title="PeerScribe">
From the practice of {loggedInNpub}
<Button size="small" onPress={() => {setShowImportNsec(true)}} >Edit!</Button>
<Button
size="small"
onPress={() => {
setShowImportNsec(true);
}}>
Edit!
</Button>
</Section>
<Section title="Choose a Pharmacy">
<View style={{ width: width - 40 }}>
<Dropdown data={locationData} labelField={'label'} valueField={'label'} onChange={handleLocationChange} value={locationData[0]}
renderItem={renderItem} style={{ width: "100%" }} placeholderStyle={{ color: "white" }} selectedTextStyle={{ color: 'white' }} />
<View style={{width: width - 40}}>
<Dropdown
data={locationData}
labelField={'label'}
valueField={'label'}
onChange={handleLocationChange}
value={locationData[0]}
renderItem={renderItem}
style={{width: '100%'}}
placeholderStyle={{color: 'white'}}
selectedTextStyle={{color: 'white'}}
/>
</View>
</Section>
<Section title="Prescription">
<View style={{ display: 'flex', flexDirection: 'column', width: "100%" }}>
{form.fields.map((field: V1Field) => {
return (
<Card
key={field.questionId}
style={{
display: 'flex',
flexDirection: 'column',
padding: 10,
backgroundColor: Colors.white,
margin: 10,
width: 350,
height: 'auto',
}}>
<Text
style={{
color: "#000000",
}}>
{field.question}
</Text>
{/* <Text
style={{
color: Colors.light,
}}>
{field.answerType}
</Text> */}
<InputFiller answerSettings={field.answerSettings} answerType={field.answerType} onChange={
(answer) => handleFormItemChange(field.questionId, answer)} />
</Card>
);
})}
<Button type='primary' onPress={handleButtonPress}> Create RX </Button>
<View style={{display: 'flex', flexDirection: 'column', width: '100%'}}>
<PatientForm nestedFormCallback={nestedFormCallback} />
<AddressForm nestedFormCallback={nestedFormCallback} />
<Button type="primary" onPress={handleButtonPress}>
<Text
style={[
{
color: Colors.light,
},
]}>
{' '}
Create RX{' '}
</Text>
</Button>
</View>
</Section>
<ImportNsec isVisible={showImportNsec} onClose={() => { setShowImportNsec(false)}} onPress={handleImportNsec}/>
<ImportNsec
isVisible={showImportNsec}
onClose={() => {
setShowImportNsec(false);
}}
onPress={handleImportNsec}
/>
</View>
);
};

View File

@@ -0,0 +1,39 @@
import {Dimensions, StyleSheet} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
export const styles = StyleSheet.create({
input: {
height: 40,
margin: 12,
borderWidth: 1,
borderBottomColor: 'white',
padding: 10,
color: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
width: Dimensions.get('window').width - 80,
color: Colors.white,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.white,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.white,
},
highlight: {
fontWeight: '500',
},
});
export const TextTheme = [
{
color: Colors.white,
},
];

View File

@@ -12,6 +12,7 @@
"dependencies": {
"@ant-design/react-native": "^5.1.0",
"@formstr/sdk": "^0.0.4-alpha",
"@react-native-community/datetimepicker": "^8.0.1",
"@react-native-community/segmented-control": "^2.2.2",
"@react-native-community/slider": "^4.5.0",
"@react-native-picker/picker": "^2.6.1",
@@ -21,6 +22,7 @@
"react": "18.2.0",
"react-native": "0.73.4",
"react-native-crypto": "^2.2.0",
"react-native-date-picker": "^5.0.3",
"react-native-element-dropdown": "^2.10.4",
"react-native-encrypted-storage": "^4.0.3",
"react-native-get-random-values": "^1.11.0",

View File

@@ -1775,6 +1775,13 @@
prompts "^2.4.2"
semver "^7.5.2"
"@react-native-community/datetimepicker@^8.0.1":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@react-native-community/datetimepicker/-/datetimepicker-8.0.1.tgz#047f27566fb21b5095fa54f558bffd8ab6472b46"
integrity sha512-4BO0t3geMNNw9cIIm9p9FNUzwMXexdzD4pAH0AaUAycs3BS71HLrX8jHbrI7nzq/+8O7cLAXn5Gudte+YpTV8Q==
dependencies:
invariant "^2.2.4"
"@react-native-community/segmented-control@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@react-native-community/segmented-control/-/segmented-control-2.2.2.tgz#4014256819ab8f40f6bc3a3929ff14a9d149cf04"
@@ -6587,6 +6594,11 @@ react-native-crypto@^2.2.0:
public-encrypt "^4.0.0"
randomfill "^1.0.3"
react-native-date-picker@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-5.0.3.tgz#8fc5a3e2dc62ad689cb54f7a1a8083db269212ae"
integrity sha512-pA/HcnB7RBac/CigQcqvM95JiD4c7mN5DPie3c/LFBol55ntvpxyxxr5ixAonB5PYLTjop21EIajAHKAP7/JeQ==
react-native-element-dropdown@^2.10.4:
version "2.10.4"
resolved "https://registry.yarnpkg.com/react-native-element-dropdown/-/react-native-element-dropdown-2.10.4.tgz#58d8a5e38d2a3fb74498c195bd775d9e1536e6bd"