Compare commits
3 Commits
240f73ab5f
...
8746d3c400
Author | SHA1 | Date |
---|---|---|
Marvin Sextro | 8746d3c400 | |
Marvin Sextro | c12e0f5d2e | |
Marvin Sextro | be72026d54 |
|
@ -0,0 +1,21 @@
|
||||||
|
interface ButtonProps {
|
||||||
|
text?: string,
|
||||||
|
icon?: string,
|
||||||
|
onClick: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
function Button(props: ButtonProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={props.onClick}
|
||||||
|
className="focus:outline-none h-20 bg-gray-400 dark:bg-gray-600 hover:bg-gray-500 text-white font-semibold rounded-md items-center flex justify-center">
|
||||||
|
{
|
||||||
|
props.icon && <img src={props.icon} className="w-12 h-12 mr-2 -ml-4" />
|
||||||
|
}
|
||||||
|
{props.text}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Button;
|
|
@ -13,6 +13,7 @@ import {getPayloadBodyFromFile, getPayloadBodyFromQR} from "../src/process";
|
||||||
import {PassData} from "../src/pass";
|
import {PassData} from "../src/pass";
|
||||||
import {COLORS} from "../src/colors";
|
import {COLORS} from "../src/colors";
|
||||||
import Colors from './Colors';
|
import Colors from './Colors';
|
||||||
|
import Button from './Button';
|
||||||
|
|
||||||
function Form(): JSX.Element {
|
function Form(): JSX.Element {
|
||||||
const {t} = useTranslation(['index', 'errors', 'common']);
|
const {t} = useTranslation(['index', 'errors', 'common']);
|
||||||
|
@ -61,7 +62,7 @@ function Form(): JSX.Element {
|
||||||
}, [inputFile])
|
}, [inputFile])
|
||||||
|
|
||||||
// Whether Safari is used or not
|
// Whether Safari is used or not
|
||||||
let [isSafari, setIsSafari] = useState<boolean>(false);
|
let [isSafari, setIsSafari] = useState<boolean>(true);
|
||||||
|
|
||||||
// Check if Safari is used
|
// Check if Safari is used
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -75,6 +76,29 @@ function Form(): JSX.Element {
|
||||||
)
|
)
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Whether Safari is used or not
|
||||||
|
let [isShareDialogAvailable, setIsShareDialogAvailable] = useState<boolean>(false);
|
||||||
|
|
||||||
|
// Check if share dialog is available
|
||||||
|
useEffect(() => {
|
||||||
|
setIsShareDialogAvailable(window.navigator && window.navigator.share !== undefined);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Open share dialog
|
||||||
|
async function showShareDialog() {
|
||||||
|
const shareData = {
|
||||||
|
title: document.title,
|
||||||
|
text: t('common:title') + ' – ' + t('common:subtitle'),
|
||||||
|
url: window.location.protocol + "//" + window.location.host,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await window.navigator.share(shareData);
|
||||||
|
} catch(error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Show file Dialog
|
// Show file Dialog
|
||||||
async function showFileDialog() {
|
async function showFileDialog() {
|
||||||
inputFile.current.click();
|
inputFile.current.click();
|
||||||
|
@ -183,18 +207,8 @@ function Form(): JSX.Element {
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<p>{t('index:selectCertificateDescription')}</p>
|
<p>{t('index:selectCertificateDescription')}</p>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||||
<button
|
<Button text={isCameraOpen ? t('index:stopCamera') : t('index:startCamera')} onClick={isCameraOpen ? hideCameraView : showCameraView} />
|
||||||
type="button"
|
<Button text={t('index:openFile')} onClick={showFileDialog} />
|
||||||
onClick={isCameraOpen ? hideCameraView : showCameraView}
|
|
||||||
className="focus:outline-none h-20 bg-gray-400 dark:bg-gray-600 hover:bg-gray-500 text-white font-semibold rounded-md">
|
|
||||||
{isCameraOpen ? t('index:stopCamera') : t('index:startCamera')}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={showFileDialog}
|
|
||||||
className="focus:outline-none h-20 bg-gray-400 dark:bg-gray-600 hover:bg-gray-500 text-white font-semibold rounded-md">
|
|
||||||
{t('index:openFile')}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<video id="cameraPreview"
|
<video id="cameraPreview"
|
||||||
|
@ -276,11 +290,21 @@ function Form(): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}/>
|
}/>
|
||||||
|
{
|
||||||
|
errorMessage && <Alert isWarning={false} message={errorMessage} onClose={() => setErrorMessage(undefined)}/>
|
||||||
|
}
|
||||||
|
<Card content={
|
||||||
|
<div className={`${isShareDialogAvailable ? "md:grid-cols-2": ""} grid-cols-1 grid gap-5`}>
|
||||||
|
{
|
||||||
|
isShareDialogAvailable && <Button text={t('index:share')} onClick={showShareDialog} />
|
||||||
|
}
|
||||||
|
<Button icon="kofi.png" text={t('common:donate')} onClick={() => {
|
||||||
|
window.open('https://ko-fi.com/marvinsxtr', '_blank');
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
}/>
|
||||||
</form>
|
</form>
|
||||||
<canvas id="canvas" style={{display: "none"}}/>
|
<canvas id="canvas" style={{display: "none"}}/>
|
||||||
{
|
|
||||||
errorMessage && <Alert isWarning={false} message={errorMessage} onClose={() => setErrorMessage(undefined)}/>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ function Page(props: PageProps): JSX.Element {
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<nav className="nav flex flex-row space-x-4 justify-center text-md font-bold flex-wrap">
|
<nav className="nav flex flex-row space-x-4 justify-center text-md font-bold flex-wrap">
|
||||||
<a href="https://ko-fi.com/marvinsxtr" className="hover:underline">{t('common:donate')}</a>
|
|
||||||
<a href="https://github.com/marvinsxtr/covidpass" className="hover:underline">{t('common:gitHub')}</a>
|
<a href="https://github.com/marvinsxtr/covidpass" className="hover:underline">{t('common:gitHub')}</a>
|
||||||
<Link href="/privacy"><a className="hover:underline">{t('common:privacyPolicy')}</a></Link>
|
<Link href="/privacy"><a className="hover:underline">{t('common:privacyPolicy')}</a></Link>
|
||||||
<Link href="/imprint"><a className="hover:underline">{t('common:imprint')}</a></Link>
|
<Link href="/imprint"><a className="hover:underline">{t('common:imprint')}</a></Link>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -24,4 +24,5 @@ iAcceptThe: Ich akzeptiere die
|
||||||
privacyPolicy: Datenschutzerklärung
|
privacyPolicy: Datenschutzerklärung
|
||||||
createdOnDevice: Auf Deinem Gerät erstellt
|
createdOnDevice: Auf Deinem Gerät erstellt
|
||||||
openSourceTransparent: Open Source und transparent
|
openSourceTransparent: Open Source und transparent
|
||||||
hostedInEU: In der EU gehostet
|
hostedInEU: In der EU gehostet
|
||||||
|
share: Weiterempfehlen
|
|
@ -25,3 +25,4 @@ privacyPolicy: Πολιτική Απορρήτου
|
||||||
createdOnDevice: Δημιουργείται στη συσκευή σας
|
createdOnDevice: Δημιουργείται στη συσκευή σας
|
||||||
openSourceTransparent: Ανοιχτού κώδικα και διαφανής
|
openSourceTransparent: Ανοιχτού κώδικα και διαφανής
|
||||||
hostedInEU: Φιλοξενείται στην ΕΕ
|
hostedInEU: Φιλοξενείται στην ΕΕ
|
||||||
|
share: Συστήσει
|
|
@ -24,4 +24,5 @@ iAcceptThe: I accept the
|
||||||
privacyPolicy: Privacy Policy
|
privacyPolicy: Privacy Policy
|
||||||
createdOnDevice: Created on your device
|
createdOnDevice: Created on your device
|
||||||
openSourceTransparent: Open source and transparent
|
openSourceTransparent: Open source and transparent
|
||||||
hostedInEU: Hosted in the EU
|
hostedInEU: Hosted in the EU
|
||||||
|
share: Share
|
|
@ -24,4 +24,5 @@ iAcceptThe: Acepto la
|
||||||
privacyPolicy: Política de Privacidad
|
privacyPolicy: Política de Privacidad
|
||||||
createdOnDevice: Creado en su dispositivo
|
createdOnDevice: Creado en su dispositivo
|
||||||
openSourceTransparent: Open source y transparente
|
openSourceTransparent: Open source y transparente
|
||||||
hostedInEU: Alojado en la UE
|
hostedInEU: Alojado en la UE
|
||||||
|
share: Recomendar
|
|
@ -24,4 +24,5 @@ iAcceptThe: Hyväksyn
|
||||||
privacyPolicy: Tietosuojaselosteen
|
privacyPolicy: Tietosuojaselosteen
|
||||||
createdOnDevice: Luotu laitteellasi
|
createdOnDevice: Luotu laitteellasi
|
||||||
openSourceTransparent: Avoin lähdekoodi ja läpinäkyvä
|
openSourceTransparent: Avoin lähdekoodi ja läpinäkyvä
|
||||||
hostedInEU: Isännöidään EU:ssa.
|
hostedInEU: Isännöidään EU:ssa.
|
||||||
|
share: Suosittele
|
|
@ -24,4 +24,5 @@ iAcceptThe: J'accepte la
|
||||||
privacyPolicy: Politique de confidentialité
|
privacyPolicy: Politique de confidentialité
|
||||||
createdOnDevice : Créé sur votre appareil
|
createdOnDevice : Créé sur votre appareil
|
||||||
openSourceTransparent : Open source et transparent
|
openSourceTransparent : Open source et transparent
|
||||||
hostedInEU : Hébergé dans l'UE
|
hostedInEU : Hébergé dans l'UE
|
||||||
|
share: Recommander
|
|
@ -25,3 +25,4 @@ privacyPolicy: Privacy Policy
|
||||||
createdOnDevice: Creato sul tuo dispositivo
|
createdOnDevice: Creato sul tuo dispositivo
|
||||||
openSourceTransparent: Open source e trasparente
|
openSourceTransparent: Open source e trasparente
|
||||||
hostedInEU: Server nell'UE
|
hostedInEU: Server nell'UE
|
||||||
|
share: Raccomandare
|
|
@ -25,3 +25,4 @@ privacyPolicy: Personvernerklæring
|
||||||
createdOnDevice: Laget på enheten din
|
createdOnDevice: Laget på enheten din
|
||||||
openSourceTransparent: Åpen kildekode og gjennomsiktig
|
openSourceTransparent: Åpen kildekode og gjennomsiktig
|
||||||
hostedInEU: Driftet i EU
|
hostedInEU: Driftet i EU
|
||||||
|
share: Anbefale
|
|
@ -24,4 +24,5 @@ iAcceptThe: Ik accepteer het
|
||||||
privacyPolicy: Privacybeleid
|
privacyPolicy: Privacybeleid
|
||||||
createdOnDevice: Aangemaakt op uw apparaat
|
createdOnDevice: Aangemaakt op uw apparaat
|
||||||
openSourceTransparent: Open source en transparant
|
openSourceTransparent: Open source en transparant
|
||||||
hostedInEU: Gehost in de EU
|
hostedInEU: Gehost in de EU
|
||||||
|
share: Aanbevelen
|
|
@ -24,4 +24,5 @@ iAcceptThe: Jag godtar
|
||||||
privacyPolicy: integritetspolicyn
|
privacyPolicy: integritetspolicyn
|
||||||
createdOnDevice: Skapad på din enhet
|
createdOnDevice: Skapad på din enhet
|
||||||
openSourceTransparent: Öppen källkod och transparent
|
openSourceTransparent: Öppen källkod och transparent
|
||||||
hostedInEU: Drivs från EU
|
hostedInEU: Drivs från EU
|
||||||
|
share: Rekommendera
|
Loading…
Reference in New Issue