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

View File

@@ -1,7 +1,15 @@
import { DatePicker, DatePickerView, InputItem, List, Text, TextareaItem, View } from "@ant-design/react-native"; import {
import { V1AnswerSettings, AnswerTypes } from "@formstr/sdk/dist/interfaces"; DatePicker,
import { useState } from "react"; DatePickerView,
import RNPickerSelect from "react-native-picker-select" 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 { interface InputFillerProps {
answerType: AnswerTypes; answerType: AnswerTypes;
@@ -16,39 +24,38 @@ export const InputFiller: React.FC<InputFillerProps> = ({
onChange, onChange,
defaultValue, defaultValue,
}) => { }) => {
const [inputValue, setInputValue] = useState('');
const [inputValue, setInputValue] = useState(""); const handleInputChange = (e: any) => {
const handleInputChange = ( console.log('E is', e);
e: any
) => {
console.log("E is", e)
setInputValue(e); setInputValue(e);
onChange(e) onChange(e);
}; };
const handleValueChange = (value: string) => { const handleValueChange = (value: string) => {
if (!value) return; if (!value) return;
setInputValue(value) setInputValue(value);
onChange(value); onChange(value);
}; };
const getInput = ( const getInput = (
answerType: AnswerTypes, answerType: AnswerTypes,
answerSettings: V1AnswerSettings answerSettings: V1AnswerSettings,
) => { ) => {
const dropdownItems = (answerSettings.choices || []).map((choice) => { const dropdownItems = (answerSettings.choices || []).map(choice => {
return { return {
label: choice.label, value: choice.choiceId, key: choice.choiceId label: choice.label,
}}) value: choice.choiceId,
const INPUT_TYPE_COMPONENT_MAP: { [key in AnswerTypes]?: JSX.Element } = { key: choice.choiceId,
};
});
const INPUT_TYPE_COMPONENT_MAP: {[key in AnswerTypes]?: JSX.Element} = {
[AnswerTypes.label]: <></>, [AnswerTypes.label]: <></>,
[AnswerTypes.shortText]: ( [AnswerTypes.shortText]: (
<InputItem <InputItem
onChange={handleValueChange} onChange={handleValueChange}
defaultValue={defaultValue as string} defaultValue={defaultValue as string}
placeholder="enter a value..." placeholder="enter a value..."
placeholderTextColor="#aaaaaa"> placeholderTextColor="#aaaaaa"></InputItem>
</InputItem>
), ),
[AnswerTypes.paragraph]: ( [AnswerTypes.paragraph]: (
<TextareaItem <TextareaItem
@@ -57,53 +64,36 @@ export const InputFiller: React.FC<InputFillerProps> = ({
placeholderTextColor="#aaaaaa" placeholderTextColor="#aaaaaa"
onChange={handleInputChange} onChange={handleInputChange}
autoHeight autoHeight
style={{ paddingVertical: 5 }} style={{paddingVertical: 5}}
/> />
), ),
[AnswerTypes.number]: ( [AnswerTypes.number]: <View></View>,
// <InputNumber [AnswerTypes.radioButton]: <View></View>,
// defaultValue={defaultValue as string} [AnswerTypes.checkboxes]: <View></View>,
// 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.dropdown]: ( [AnswerTypes.dropdown]: (
<RNPickerSelect <RNPickerSelect
onValueChange={handleValueChange} onValueChange={handleValueChange}
items={dropdownItems} items={dropdownItems}
placeholder={{}} placeholder={{}}
key="picker" key="picker"
value={inputValue} value={inputValue}>
><Text>{inputValue ? answerSettings.choices?.filter((choice) => { return choice.choiceId === inputValue})[0].label : "Select an option"}</Text></RNPickerSelect> <Text>
{inputValue
? answerSettings.choices?.filter(choice => {
return choice.choiceId === inputValue;
})[0].label
: 'Select an option'}
</Text>
</RNPickerSelect>
), ),
[AnswerTypes.date]: ( [AnswerTypes.date]: (
<List> <List>
<DatePicker key="Datepicker" /> <DatePicker key="Datepicker" />
</List> </List>
), ),
[AnswerTypes.time]: ( [AnswerTypes.time]: (
<List> <List>
<DatePicker key="time" /> <DatePicker key="time" />
</List> </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 {Alert, Appearance, Dimensions, Image, Text, View} from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen'; import {Colors} from 'react-native/Libraries/NewAppScreen';
import { PropsWithChildren, useEffect, useState } from 'react'; import {PropsWithChildren, useEffect, useState} from 'react';
import { Button, Card, Modal } from '@ant-design/react-native'; import {Button, Card, Modal} from '@ant-design/react-native';
import { V1Field } from '@formstr/sdk/dist/interfaces';
import { InputFiller } from '../Inputs/Inputs';
// import { SendPrescription } from './sendPrescription'; // import { SendPrescription } from './sendPrescription';
import { Dropdown } from 'react-native-element-dropdown'; import {Dropdown} from 'react-native-element-dropdown';
import { SimplePool, UnsignedEvent, finalizeEvent, generateSecretKey, getPublicKey, nip04, nip19 } from 'nostr-tools'; import {
SimplePool,
UnsignedEvent,
finalizeEvent,
generateSecretKey,
getPublicKey,
nip04,
nip19,
} from 'nostr-tools';
import EncryptedStorage from 'react-native-encrypted-storage'; import EncryptedStorage from 'react-native-encrypted-storage';
import { ImportNsec } from './ImportNsec'; import {ImportNsec} from './ImportNsec';
import { json2xml } from 'xml-js'; 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) { function OBJtoXML(obj: any) {
var xml = ''; var xml = '';
for (var prop in obj) { for (var prop in obj) {
xml += "<" + prop + ">"; xml += '<' + prop + '>';
if(Array.isArray(obj[prop])) { if (Array.isArray(obj[prop])) {
for (var array of obj[prop]) { for (var array of obj[prop]) {
// A real botch fix here
xml += '</' + prop + '>';
xml += '<' + prop + '>';
// A real botch fix here xml += OBJtoXML(new Object(array));
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 += "</" + 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,''); var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
return xml return xml;
} }
type SectionProps = PropsWithChildren<{
title: string;
}>;
const colorScheme = Appearance.getColorScheme(); const colorScheme = Appearance.getColorScheme();
const backgroundStyle = { const backgroundStyle = {
backgroundColor: Colors.darker, 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 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 = [ 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 A',
{ label: 'Pharmacy C', value: 'C', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://relay.hllo.live"] }, value: 'A',
{ label: 'Pharmacy D', value: 'D', npub: 'npub1tea09rtjeuzgk4gjajzry37wuyv7h02d4zw38cpadcrkg5yt0qhqncr7km', relays: ["wss://nos.lol", "wss://relay.damus.io"] } 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 = [ const locationDummyData = [{label: 'Pharmacy A', value: 'A'}];
{ label: 'Pharmacy A', value: 'A' }
]
export const PrescriptionCreator = ({ form }: { form: any }) => { export const PrescriptionCreator = () => {
if (form === null) return <View style={{ backgroundColor: "#ffffff" }}><Text style={{ color: "#000000" }}>Loading...</Text></View>
const [showImportNsec, setShowImportNsec] = useState(false); const [showImportNsec, setShowImportNsec] = useState(false);
const [loggedInNpub, setLoggedInNpub] = useState("") const [loggedInNpub, setLoggedInNpub] = useState('');
const [selectedPharmacyId, setSelectedPharmacyId] = useState(locationData[0].npub); const [selectedPharmacyId, setSelectedPharmacyId] = useState(
locationData[0].npub,
);
const [selectedPharmacyRelays, setSelectedPharmacyRelays] = useState([]); const [selectedPharmacyRelays, setSelectedPharmacyRelays] = useState([]);
const [finalJSON, setFinalJson] = useState({}) const [finalJSON, setFinalJson] = useState({});
useEffect(() => { useEffect(() => {
async function initialize() { async function initialize() {
let doctorCredentials = null; let doctorCredentials = null;
try { try {
doctorCredentials = await EncryptedStorage.getItem("user_credentials"); doctorCredentials = await EncryptedStorage.getItem('user_credentials');
if(!doctorCredentials) { if (!doctorCredentials) {
setShowImportNsec(true) setShowImportNsec(true);
} else {
setLoggedInNpub(
nip19.npubEncode(
getPublicKey(nip19.decode(doctorCredentials).data as Uint8Array),
),
);
} }
else { } catch (e) {
setLoggedInNpub(nip19.npubEncode(getPublicKey(nip19.decode(doctorCredentials).data as Uint8Array))) console.log('Error getting credentials', e);
}
}
catch(e) {
console.log("Error getting credentials", e)
} }
} }
initialize() initialize();
}, []) }, []);
const renderItem = (item: any) => { const renderItem = (item: any) => {
return <View style={{ width: width, display: 'flex', flexDirection: 'column', padding: 10, flexWrap: "wrap" }}> return (
<Text style={{ color: "black", fontSize: 24 }}>{item.label}</Text> <View
<View style={{ width: width - 100 }}> style={{
<Text style={{ color: 'grey', paddingBottom: 5 }}>Npub: {item.npub}</Text> width: width,
<Text style={{ color: 'grey' }}>Relays: {item.relays.join(', ')}</Text> 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>
</View> );
} };
const handleFormItemChange = (questionId: string, value: string) => { const nestedFormCallback = (
console.log("Filling", questionId, value) xmlTag: string,
setFinalJson({...finalJSON, [questionId]: value}) value: Object | Array<any> | string,
} ) => {
console.log('Filling', xmlTag, value);
setFinalJson({...finalJSON, [xmlTag]: value});
};
const handleLocationChange = (item: any) => { const handleLocationChange = (item: any) => {
setSelectedPharmacyId(item.npub) setSelectedPharmacyId(item.npub);
setSelectedPharmacyRelays(item.relays) setSelectedPharmacyRelays(item.relays);
} };
const handleImportNsec = (nsec: string) => { const handleImportNsec = (nsec: string) => {
EncryptedStorage.setItem("user_credentials", nsec) EncryptedStorage.setItem('user_credentials', nsec);
if(nsec.startsWith('nsec1') && nsec.length !== 63) { if (nsec.startsWith('nsec1') && nsec.length !== 63) {
Alert.alert("not a valid nsec!") Alert.alert('not a valid nsec!');
return; return;
} }
setLoggedInNpub(nip19.npubEncode(getPublicKey(nip19.decode(nsec).data as Uint8Array))) setLoggedInNpub(
setShowImportNsec(false) nip19.npubEncode(getPublicKey(nip19.decode(nsec).data as Uint8Array)),
} );
setShowImportNsec(false);
};
const handleButtonPress = () => { const handleButtonPress = () => {
console.log("Final JSON is", finalJSON) console.log('Final JSON is', finalJSON);
const xml = OBJtoXML({form: finalJSON }) const xml = OBJtoXML({prescription: finalJSON});
console.log("XML is...", xml, typeof xml ) console.log('XML is...', xml, typeof xml);
sendPrescription(xml); sendPrescription(xml);
} };
const sendPrescription = async (xml: string) => { const sendPrescription = async (xml: string) => {
console.log("Will generate IDs") console.log('Will generate IDs');
const sk = nip19.decode(await EncryptedStorage.getItem("user_credentials") as `nsec1${string}`).data as Uint8Array const sk = nip19.decode(
const pk = getPublicKey(sk) (await EncryptedStorage.getItem('user_credentials')) as `nsec1${string}`,
const pharmacyId = nip19.decode(selectedPharmacyId).data as string ).data as Uint8Array;
console.log("Got ids") const pk = getPublicKey(sk);
const pharmacyId = nip19.decode(selectedPharmacyId).data as string;
console.log('Got ids');
console.log('content is ', xml);
const baseKind4Event: UnsignedEvent = { const baseKind4Event: UnsignedEvent = {
kind: 4, kind: 4,
tags: [["p", pharmacyId]], tags: [['p', pharmacyId]],
content: await nip04.encrypt(sk, pharmacyId, `This is a test prescription from PeerScribe ${xml}`), content: await nip04.encrypt(sk, pharmacyId, `${xml}`),
created_at: Math.floor(Date.now() / 1000), created_at: Math.floor(Date.now() / 1000),
pubkey: pk pubkey: pk,
} };
const finalEvent = finalizeEvent(baseKind4Event, sk) const finalEvent = finalizeEvent(baseKind4Event, sk);
const pool = new SimplePool() const pool = new SimplePool();
console.log("publishing event") console.log('publishing event');
await Promise.any(pool.publish(selectedPharmacyRelays, finalEvent)) await Promise.any(pool.publish(selectedPharmacyRelays, finalEvent));
console.log("Event Published") console.log('Event Published');
Alert.alert("Prescription Sent to the pharmacy!") Alert.alert('Prescription Sent to the pharmacy!');
} };
return ( return (
<View <View
@@ -199,58 +220,60 @@ export const PrescriptionCreator = ({ form }: { form: any }) => {
width: Dimensions.get('window').width, width: Dimensions.get('window').width,
}} }}
source={{ source={{
uri: form.settings.titleImageUrl, uri: 'https://www.studentdoctor.net/wp-content/uploads/2018/08/20180815_prescription.png',
}} }}
/> />
<Section title="PeerScribe"> <Section title="PeerScribe">
From the practice of {loggedInNpub} From the practice of {loggedInNpub}
<Button size="small" onPress={() => {setShowImportNsec(true)}} >Edit!</Button> <Button
size="small"
onPress={() => {
setShowImportNsec(true);
}}>
Edit!
</Button>
</Section> </Section>
<Section title="Choose a Pharmacy"> <Section title="Choose a Pharmacy">
<View style={{ width: width - 40 }}> <View style={{width: width - 40}}>
<Dropdown data={locationData} labelField={'label'} valueField={'label'} onChange={handleLocationChange} value={locationData[0]} <Dropdown
renderItem={renderItem} style={{ width: "100%" }} placeholderStyle={{ color: "white" }} selectedTextStyle={{ color: 'white' }} /> data={locationData}
labelField={'label'}
valueField={'label'}
onChange={handleLocationChange}
value={locationData[0]}
renderItem={renderItem}
style={{width: '100%'}}
placeholderStyle={{color: 'white'}}
selectedTextStyle={{color: 'white'}}
/>
</View> </View>
</Section> </Section>
<Section title="Prescription"> <Section title="Prescription">
<View style={{ display: 'flex', flexDirection: 'column', width: "100%" }}> <View style={{display: 'flex', flexDirection: 'column', width: '100%'}}>
{form.fields.map((field: V1Field) => { <PatientForm nestedFormCallback={nestedFormCallback} />
return ( <AddressForm nestedFormCallback={nestedFormCallback} />
<Card <Button type="primary" onPress={handleButtonPress}>
key={field.questionId} <Text
style={{ style={[
display: 'flex', {
flexDirection: 'column', color: Colors.light,
padding: 10, },
backgroundColor: Colors.white, ]}>
margin: 10, {' '}
width: 350, Create RX{' '}
height: 'auto', </Text>
}}> </Button>
<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> </View>
</Section> </Section>
<ImportNsec isVisible={showImportNsec} onClose={() => { setShowImportNsec(false)}} onPress={handleImportNsec}/> <ImportNsec
isVisible={showImportNsec}
onClose={() => {
setShowImportNsec(false);
}}
onPress={handleImportNsec}
/>
</View> </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": { "dependencies": {
"@ant-design/react-native": "^5.1.0", "@ant-design/react-native": "^5.1.0",
"@formstr/sdk": "^0.0.4-alpha", "@formstr/sdk": "^0.0.4-alpha",
"@react-native-community/datetimepicker": "^8.0.1",
"@react-native-community/segmented-control": "^2.2.2", "@react-native-community/segmented-control": "^2.2.2",
"@react-native-community/slider": "^4.5.0", "@react-native-community/slider": "^4.5.0",
"@react-native-picker/picker": "^2.6.1", "@react-native-picker/picker": "^2.6.1",
@@ -21,6 +22,7 @@
"react": "18.2.0", "react": "18.2.0",
"react-native": "0.73.4", "react-native": "0.73.4",
"react-native-crypto": "^2.2.0", "react-native-crypto": "^2.2.0",
"react-native-date-picker": "^5.0.3",
"react-native-element-dropdown": "^2.10.4", "react-native-element-dropdown": "^2.10.4",
"react-native-encrypted-storage": "^4.0.3", "react-native-encrypted-storage": "^4.0.3",
"react-native-get-random-values": "^1.11.0", "react-native-get-random-values": "^1.11.0",

View File

@@ -1775,6 +1775,13 @@
prompts "^2.4.2" prompts "^2.4.2"
semver "^7.5.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": "@react-native-community/segmented-control@^2.2.2":
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/@react-native-community/segmented-control/-/segmented-control-2.2.2.tgz#4014256819ab8f40f6bc3a3929ff14a9d149cf04" 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" public-encrypt "^4.0.0"
randomfill "^1.0.3" 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: react-native-element-dropdown@^2.10.4:
version "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" resolved "https://registry.yarnpkg.com/react-native-element-dropdown/-/react-native-element-dropdown-2.10.4.tgz#58d8a5e38d2a3fb74498c195bd775d9e1536e6bd"