frontend/app/components/settings/install-app.tsx
Nathan Lamy 8b57952344
All checks were successful
Deploy to Netlify / Deploy to Netlify (push) Successful in 1m30s
feat: add subscribe logic
2025-08-19 22:36:23 +02:00

123 lines
4.2 KiB
TypeScript

import {
ChevronDown,
Chrome,
Info,
MoreVertical,
Share,
Smartphone,
} from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
import { Button } from "../ui/button";
import { CardDescription } from "../ui/card";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@radix-ui/react-accordion";
import { Separator } from "../ui/separator";
import { useEffect, useState } from "react";
export default function InstallApp() {
const [supportsPWA, setSupportsPWA] = useState(false);
const [promptInstall, setPromptInstall] = useState<any>(null);
useEffect(() => {
const handler = (e: any) => {
e.preventDefault();
console.log("we are being triggered :D");
setSupportsPWA(true);
setPromptInstall(e);
};
window.addEventListener("beforeinstallprompt", handler);
return () => window.removeEventListener("beforeinstallprompt", handler);
}, []);
const onClick = (evt: React.MouseEvent<HTMLButtonElement>) => {
evt.preventDefault();
if (!promptInstall) {
return;
}
promptInstall.prompt();
};
return (
<>
<Alert className="bg-blue-50 border border-blue-200 dark:bg-blue-900 dark:border-blue-700">
<Info className="text-blue-600! dark:text-blue-400! h-5 w-5" />
<AlertTitle className="text-blue-900 dark:text-white">
Informations importantes
</AlertTitle>
<AlertDescription>
<ul className="space-y-1 text-blue-800 dark:text-blue-300">
<li>
Pour recevoir des notifications, vous devez installer notre
application sur votre appareil.
</li>
<li>
Vous devrez autoriser les notifications lorsque l'application
vous le demandera.
</li>
</ul>
</AlertDescription>
</Alert>
{/* Install PWA button */}
<Button className="w-full" onClick={onClick} disabled={!supportsPWA}>
<Smartphone className="h-4 w-4 sm:h-5 sm:w-5 mr-2" />
Installer l'application
</Button>
<Separator />
<CardDescription>
Si le bouton ci-dessus ne fonctionne pas, suivez ces étapes :
</CardDescription>
<Accordion type="multiple" className="w-full space-y-4">
<AccordionItem value="android">
<AccordionTrigger className="flex items-center gap-1 group">
<h4>Instructions Android (Chrome)</h4>
<ChevronDown className="w-4 h-4 text-primary transition-transform group-data-[state=open]:rotate-180" />
</AccordionTrigger>
<AccordionContent>
<ol className="space-y-2 list-decimal list-inside pl-6 text-muted-foreground text-sm">
<li>Ouvrez ce site avec Google Chrome</li>
<li>Appuyez sur les trois points en haut à droite</li>
<li>Sélectionnez "Ajouter à l'écran d'accueil"</li>
<li>Confirmez pour installer l'application</li>
</ol>
</AccordionContent>
</AccordionItem>
<AccordionItem value="ios">
<AccordionTrigger className="flex items-center gap-1 group">
<h4>Instructions iOS (Safari)</h4>
<ChevronDown className="w-4 h-4 text-primary transition-transform group-data-[state=open]:rotate-180" />
</AccordionTrigger>
<AccordionContent>
<ol className="space-y-2 list-decimal list-inside pl-6 text-muted-foreground text-sm">
<li>Ouvrez ce site avec Safari</li>
<li>
Appuyez sur l'icône de partage en bas (le carré avec une flèche)
</li>
<li>
Faites défiler vers le bas et sélectionnez "Sur l'écran
d'accueil"
</li>
<li>Confirmez pour installer l'application</li>
</ol>
</AccordionContent>
</AccordionItem>
</Accordion>
</>
);
}
export function isInstalled() {
const UA = navigator.userAgent;
const IOS = UA.match(/iPhone|iPad|iPod/);
const standalone = window.matchMedia("(display-mode: standalone)").matches;
return !!(standalone || (IOS && !UA.match(/Safari/)));
}