mirror of
https://github.com/abhay-raizada/PeerScribe.git
synced 2026-04-26 16:24:03 +00:00
183 lines
5.5 KiB
TypeScript
183 lines
5.5 KiB
TypeScript
import {Alert, Dimensions, Image, View, Button} from 'react-native';
|
|
import {Colors} from 'react-native/Libraries/NewAppScreen';
|
|
import {useEffect, useState} from 'react';
|
|
import {
|
|
SimplePool,
|
|
UnsignedEvent,
|
|
finalizeEvent,
|
|
getPublicKey,
|
|
nip04,
|
|
nip19,
|
|
} from 'nostr-tools';
|
|
import EncryptedStorage from 'react-native-encrypted-storage';
|
|
import {ImportNsec} from '../common/ImportNsec';
|
|
import {Section} from '../common/Section';
|
|
import {PatientForm} from './PatientForm';
|
|
import {AddressForm} from './AddressForm';
|
|
import {MedicineForm} from './MedicineForm';
|
|
import {PharmacyPicker, pharmacyData} from '../PharmacyPicker';
|
|
|
|
function OBJtoXML(obj: any) {
|
|
var xml = '';
|
|
for (var prop in obj) {
|
|
xml += '<' + prop + '>';
|
|
if (Array.isArray(obj[prop])) {
|
|
for (var array of obj[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 += '</' + prop + '>';
|
|
}
|
|
var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
|
|
return xml;
|
|
}
|
|
|
|
export const PrescriptionCreator = () => {
|
|
const [showImportNsec, setShowImportNsec] = useState(false);
|
|
const [loggedInNpub, setLoggedInNpub] = useState('');
|
|
const [finalJSON, setFinalJson] = useState({});
|
|
const [selectedPharmacyId, setSelectedPharmacyId] = useState(
|
|
pharmacyData[0].npub,
|
|
);
|
|
const [selectedPharmacyRelays, setSelectedPharmacyRelays] = useState([]);
|
|
|
|
const handleLocationChange = (item: any) => {
|
|
setSelectedPharmacyId(item.npub);
|
|
setSelectedPharmacyRelays(item.relays);
|
|
};
|
|
|
|
useEffect(() => {
|
|
async function initialize() {
|
|
let doctorCredentials = null;
|
|
try {
|
|
doctorCredentials = await EncryptedStorage.getItem('user_credentials');
|
|
if (!doctorCredentials) {
|
|
setShowImportNsec(true);
|
|
} else {
|
|
setLoggedInNpub(
|
|
nip19.npubEncode(
|
|
getPublicKey(nip19.decode(doctorCredentials).data as Uint8Array),
|
|
),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
console.log('Error getting credentials', e);
|
|
}
|
|
}
|
|
initialize();
|
|
}, []);
|
|
|
|
const nestedFormCallback = (
|
|
xmlTag: string,
|
|
value: Object | Array<any> | string,
|
|
) => {
|
|
console.log('Filling', xmlTag, value);
|
|
setFinalJson({...finalJSON, [xmlTag]: value});
|
|
};
|
|
|
|
const handleImportNsec = (nsec: string) => {
|
|
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);
|
|
};
|
|
|
|
const handleButtonPress = () => {
|
|
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('content is ', xml);
|
|
const baseKind4Event: UnsignedEvent = {
|
|
kind: 4,
|
|
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.allSettled(pool.publish(selectedPharmacyRelays, finalEvent));
|
|
console.log('Event Published');
|
|
Alert.alert('Prescription Sent to the pharmacy!');
|
|
};
|
|
|
|
return (
|
|
<View
|
|
style={{
|
|
backgroundColor: Colors.black,
|
|
minHeight: Dimensions.get('window').height,
|
|
}}>
|
|
<Image
|
|
style={{
|
|
height: 100,
|
|
width: Dimensions.get('window').width,
|
|
}}
|
|
source={{
|
|
uri: 'https://www.studentdoctor.net/wp-content/uploads/2018/08/20180815_prescription.png',
|
|
}}
|
|
/>
|
|
<Section title="PeerScribe">
|
|
From the practice of {loggedInNpub}
|
|
<Button
|
|
onPress={() => {
|
|
setShowImportNsec(true);
|
|
}}
|
|
title="edit"
|
|
/>
|
|
</Section>
|
|
|
|
<PharmacyPicker handleLocationChange={handleLocationChange} />
|
|
|
|
<Section title="Create Prescription">
|
|
<View style={{display: 'flex', flexDirection: 'column', width: '100%'}}>
|
|
<Section title="Patient" collapsible={true}>
|
|
{' '}
|
|
<PatientForm nestedFormCallback={nestedFormCallback} />
|
|
</Section>
|
|
<Section title="Address" collapsible={true}>
|
|
<AddressForm nestedFormCallback={nestedFormCallback} />
|
|
</Section>
|
|
<Section title="Medicine" collapsible={true}>
|
|
<MedicineForm nestedFormCallback={nestedFormCallback} />
|
|
</Section>
|
|
<View style={{margin: 15}}>
|
|
<Button onPress={handleButtonPress} title="Create Rx" />
|
|
</View>
|
|
</View>
|
|
</Section>
|
|
<ImportNsec
|
|
isVisible={showImportNsec}
|
|
onClose={() => {
|
|
setShowImportNsec(false);
|
|
}}
|
|
onPress={handleImportNsec}
|
|
/>
|
|
</View>
|
|
);
|
|
};
|