-
- {d.vaccine_name.length > 18 ? d.vaccine_name.slice(0, 17) + '…' : d.vaccine_name}
-
+
+
+ {d.vaccine_name.length > 18 ? d.vaccine_name.slice(0, 17) + '…' : d.vaccine_name}
+
+
diff --git a/frontend/src/pages/IssuerDashboard.jsx b/frontend/src/pages/IssuerDashboard.jsx
index ab52e2f..41f4a79 100644
--- a/frontend/src/pages/IssuerDashboard.jsx
+++ b/frontend/src/pages/IssuerDashboard.jsx
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useAuth } from '../hooks/useFreighter';
import { useVaccination } from '../hooks/useVaccination';
+import { useToast } from '../hooks/useToast';
import ConfirmMintDialog from '../components/ConfirmMintDialog';
import CopyButton from '../components/CopyButton';
import RoleBadge from '../components/RoleBadge';
@@ -9,10 +10,10 @@ import RoleBadge from '../components/RoleBadge';
const styles = {
page: { maxWidth: 500, width: '100%', margin: '2rem auto', padding: '0 1rem', boxSizing: 'border-box' },
form: { display: 'flex', flexDirection: 'column', gap: '1rem' },
- input: { padding: '0.6rem 0.75rem', background: '#1e293b', border: '1px solid #334155', borderRadius: 8, color: '#e2e8f0', fontSize: '1rem', width: '100%', boxSizing: 'border-box' },
- inputError: { padding: '0.6rem 0.75rem', background: '#1e293b', border: '1px solid #f87171', borderRadius: 8, color: '#e2e8f0', fontSize: '1rem', width: '100%', boxSizing: 'border-box' },
- btn: { padding: '0.7rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 8, fontSize: '1rem', width: '100%', touchAction: 'manipulation' },
- btnDisabled: { padding: '0.7rem', background: '#334155', color: '#64748b', border: 'none', borderRadius: 8, fontSize: '1rem', cursor: 'not-allowed', width: '100%' },
+ input: { padding: '0.6rem 0.75rem', background: '#1e293b', border: '1px solid #334155', borderRadius: 8, color: '#e2e8f0', fontSize: '1rem', width: '100%', boxSizing: 'border-box', minHeight: '44px' },
+ inputError: { padding: '0.6rem 0.75rem', background: '#1e293b', border: '1px solid #f87171', borderRadius: 8, color: '#e2e8f0', fontSize: '1rem', width: '100%', boxSizing: 'border-box', minHeight: '44px' },
+ btn: { padding: '0.7rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 8, fontSize: '1rem', width: '100%', touchAction: 'manipulation', minHeight: '44px', cursor: 'pointer' },
+ btnDisabled: { padding: '0.7rem', background: '#334155', color: '#64748b', border: 'none', borderRadius: 8, fontSize: '1rem', cursor: 'not-allowed', width: '100%', minHeight: '44px' },
label: { color: '#94a3b8', fontSize: '0.85rem', marginBottom: '0.25rem' },
fieldError: { color: '#f87171', fontSize: '0.78rem', marginTop: '0.25rem' },
statusBadge: { display: 'inline-flex', alignItems: 'center', gap: '0.5rem', padding: '0.5rem 0.75rem', borderRadius: 6, fontSize: '0.85rem', marginBottom: '1rem' },
@@ -30,6 +31,7 @@ export default function IssuerDashboard() {
const { t } = useTranslation();
const { publicKey, role, connect } = useAuth();
const { issueVaccination, checkIssuerStatus, loading } = useVaccination();
+ const toast = useToast();
const [form, setForm] = useState(() => {
try {
@@ -100,6 +102,9 @@ export default function IssuerDashboard() {
setMintResult(result);
setForm(EMPTY_FORM);
sessionStorage.removeItem(FORM_KEY);
+ toast('Vaccination NFT issued successfully!', 'success');
+ } else {
+ toast('Failed to issue vaccination NFT. Please try again.', 'error');
}
};
diff --git a/frontend/src/pages/IssuerOnboarding.jsx b/frontend/src/pages/IssuerOnboarding.jsx
index a7721ed..26aef9b 100644
--- a/frontend/src/pages/IssuerOnboarding.jsx
+++ b/frontend/src/pages/IssuerOnboarding.jsx
@@ -1,18 +1,20 @@
import { useState } from 'react';
import { useAuth } from '../hooks/useFreighter';
+import { useToast } from '../hooks/useToast';
const s = {
page: { maxWidth: 520, width: '100%', margin: '2rem auto', padding: '0 1rem', boxSizing: 'border-box' },
field: { display: 'flex', flexDirection: 'column', gap: '0.35rem', marginBottom: '1rem' },
label: { color: '#94a3b8', fontSize: '0.85rem' },
- input: { padding: '0.5rem 0.75rem', background: '#1e293b', border: '1px solid #334155', borderRadius: 6, color: '#e2e8f0', fontSize: '0.9rem' },
- btn: { padding: '0.55rem 1.25rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: '0.9rem', marginTop: '0.5rem' },
+ input: { padding: '0.6rem 0.75rem', background: '#1e293b', border: '1px solid #334155', borderRadius: 6, color: '#e2e8f0', fontSize: '0.9rem', minHeight: '44px' },
+ btn: { padding: '0.7rem 1.25rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: '0.9rem', marginTop: '0.5rem', minHeight: '44px' },
success:{ marginTop: '1rem', padding: '0.75rem 1rem', background: '#14532d', borderRadius: 8, color: '#86efac', fontSize: '0.9rem' },
error: { marginTop: '0.5rem', color: '#f87171', fontSize: '0.9rem' },
};
export default function IssuerOnboarding() {
const { publicKey, connect, apiFetch } = useAuth();
+ const toast = useToast();
const [form, setForm] = useState({ name: '', license_number: '', country: '' });
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(null);
@@ -47,8 +49,10 @@ export default function IssuerOnboarding() {
if (!res.ok) throw new Error(data.error || 'Submission failed');
setSuccess(data.message);
setForm({ name: '', license_number: '', country: '' });
+ toast('Application submitted successfully!', 'success');
} catch (err) {
setError(err.message);
+ toast(`Error: ${err.message}`, 'error');
} finally {
setLoading(false);
}
diff --git a/frontend/src/pages/PatientDashboard.jsx b/frontend/src/pages/PatientDashboard.jsx
index 0c774e9..060ec5c 100644
--- a/frontend/src/pages/PatientDashboard.jsx
+++ b/frontend/src/pages/PatientDashboard.jsx
@@ -15,7 +15,7 @@ import ConsentScreen from '../components/ConsentScreen';
const styles = {
page: { maxWidth: 700, width: '100%', margin: '2rem auto', padding: '0 1rem', boxSizing: 'border-box' },
header: { borderLeft: '4px solid #0ea5e9', paddingLeft: '0.75rem', marginBottom: '1.5rem' },
- btn: { padding: '0.6rem 1.5rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 8, cursor: 'pointer' },
+ btn: { padding: '0.7rem 1.5rem', background: '#0ea5e9', color: '#fff', border: 'none', borderRadius: 8, cursor: 'pointer', minHeight: '44px', minWidth: '44px' },
};
export default function PatientDashboard() {
diff --git a/frontend/src/pages/VerifyPage.jsx b/frontend/src/pages/VerifyPage.jsx
index 5c2b771..bf088c1 100644
--- a/frontend/src/pages/VerifyPage.jsx
+++ b/frontend/src/pages/VerifyPage.jsx
@@ -7,8 +7,8 @@ import { useToast } from '../hooks/useToast';
const styles = {
page: { maxWidth: 600, margin: '2rem auto', padding: '0 1rem' },
- input: { padding: '0.6rem 0.75rem', background: 'var(--input-bg)', border: '1px solid var(--border)', borderRadius: 8, color: 'var(--text)', fontSize: '1rem', width: '100%' },
- btn: { padding: '0.6rem 1.5rem', background: 'var(--btn-primary)', color: '#fff', border: 'none', borderRadius: 8, fontSize: '1rem', marginTop: '0.75rem' },
+ input: { padding: '0.6rem 0.75rem', background: 'var(--input-bg)', border: '1px solid var(--border)', borderRadius: 8, color: 'var(--text)', fontSize: '1rem', width: '100%', boxSizing: 'border-box', minHeight: '44px' },
+ btn: { padding: '0.7rem 1.5rem', background: 'var(--btn-primary)', color: '#fff', border: 'none', borderRadius: 8, fontSize: '1rem', marginTop: '0.75rem', minHeight: '44px', cursor: 'pointer' },
};
export default function VerifyPage() {
@@ -28,6 +28,7 @@ export default function VerifyPage() {
const data = await res.json();
if (!res.ok) throw new Error(data.error);
setResult(data);
+ toast('Verification successful', 'success');
} catch (e) {
setError(e.message || 'Verification failed.');
toast(e.message || 'Verification failed.', 'error');