Add share and support buttons
This commit is contained in:
parent
240f73ab5f
commit
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" />
|
||||||
|
}
|
||||||
|
{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']);
|
||||||
|
@ -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) {
|
||||||
|
setErrorMessage(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`}>
|
||||||
|
<Button icon="kofi.png" text={t('common:donate')} onClick={() => {
|
||||||
|
window.open('https://ko-fi.com/marvinsxtr', '_blank');
|
||||||
|
}} />
|
||||||
|
{
|
||||||
|
isShareDialogAvailable && <Button text={t('common:share')} onClick={showShareDialog} />
|
||||||
|
}
|
||||||
|
</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 |
Loading…
Reference in New Issue