Duffer Derek

Current Path : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/onboarding/
Upload File :
Current File : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/onboarding/InstallPWAOverlay.tsx

// Install PWA Overlay Component
"use client";

import React, { useState, useEffect } from "react";
import { X, Smartphone } from "lucide-react";
import { isMobile, isPWA, isPWAInstallSupported } from "@/lib/deviceDetection";
import { isIOSDevice } from "@/lib/iosPWAUtils";
import { getGlobalDeferredPrompt, clearGlobalDeferredPrompt } from "@/lib/pwaInstall";
import "./pwa-overlay.scss";
import pwaInstallIcon from "../../images/pwa-overlay-install-icon.svg";
import Image from "next/image";
import tapShare from "../../images/tap-share.svg";
import homeScreenButton from "../../images/home-screen-icon.svg";
interface InstallPWAOverlayProps {
  onDismiss: () => void;
  onInstall?: () => void;
}

export const InstallPWAOverlay: React.FC<InstallPWAOverlayProps> = ({ onDismiss, onInstall }) => {
  // Only show overlay on mobile devices
  // Hide if already installed as PWA or not on mobile
  if (isPWA() || !isMobile()) {
    return null;
  }

  const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
  const [isInstalling, setIsInstalling] = useState(false);
  const [showIOSInstructions, setShowIOSInstructions] = useState(false);

  useEffect(() => {
    // Check if already installed
    if (isPWA()) {
      // console.log("Already installed as PWA");
      return;
    }

    // Check if we already have a global deferred prompt
    const existingPrompt = getGlobalDeferredPrompt();
    if (existingPrompt) {
      // console.log("Found existing global deferred prompt");
      setDeferredPrompt(existingPrompt);
    }

    // Listen for the global PWA install prompt event
    const handlePWAInstallPromptAvailable = (e: any) => {
      // console.log("PWA install prompt available event received", e.detail);
      setDeferredPrompt(e.detail);
    };

    // Listen for PWA installed event
    const handlePWAInstalled = () => {
      // console.log("PWA was installed");
      setDeferredPrompt(null);
    };

    // Add event listeners
    window.addEventListener("pwaInstallPromptAvailable", handlePWAInstallPromptAvailable);
    window.addEventListener("pwaInstalled", handlePWAInstalled);

    return () => {
      window.removeEventListener("pwaInstallPromptAvailable", handlePWAInstallPromptAvailable);
      window.removeEventListener("pwaInstalled", handlePWAInstalled);
    };
  }, []);

  const handleInstall = async () => {
    // console.log("Install button clicked, deferredPrompt:", !!deferredPrompt);

    // Handle iOS devices differently
    if (isIOSDevice()) {
      // console.log("iOS device detected - showing Add to Home Screen instructions");
      // For iOS, show the step-by-step instructions
      setShowIOSInstructions(true);
      return;
    }

    if (!deferredPrompt) {
      // console.log("No deferred prompt available, showing fallback instructions");

      // Check if PWA installation is supported but prompt not available
      if (isPWAInstallSupported()) {
        // console.log(
        //   "PWA install is supported but prompt not available - this might be a timing issue"
        // );
        // Try to get the global prompt again
        const globalPrompt = getGlobalDeferredPrompt();
        if (globalPrompt) {
          // console.log("Found global prompt, using it");
          setDeferredPrompt(globalPrompt);
          // Retry the installation
          setTimeout(() => handleInstall(), 100);
          return;
        }
      }

      // Fallback for browsers that don't support beforeinstallprompt
      onInstall?.();
      return;
    }

    setIsInstalling(true);

    try {
      // console.log("Showing install prompt...");

      // Show the install prompt
      const result = await deferredPrompt.prompt();
      // console.log("Install prompt result:", result);

      // Wait for the user to respond to the prompt
      const choiceResult = await deferredPrompt.userChoice;
      // console.log("Install prompt outcome:", choiceResult);

      if (choiceResult.outcome === "accepted") {
        // console.log("User accepted the install prompt");
        // Mark PWA as installed in localStorage
        localStorage.setItem("pwa_installed", "true");
        onInstall?.();
      } else {
        // console.log("User dismissed the install prompt");
      }
    } catch (error) {
      console.error("Error during PWA installation:", error);
      // Show fallback instructions on error
      onInstall?.();
    } finally {
      setIsInstalling(false);
      setDeferredPrompt(null);
      clearGlobalDeferredPrompt();
    }
  };

  // Debug logging
  // console.log("InstallPWAOverlay render:", {
  //   isMobile: isMobile(),
  //   isPWA: isPWA(),
  //   deferredPrompt: !!deferredPrompt,
  //   isInstalling,
  //   globalPrompt: !!getGlobalDeferredPrompt(),
  // });

  // Add debug function to window for testing
  useEffect(() => {
    if (typeof window !== "undefined") {
      (window as any).debugPWAInstall = () => {
        // console.log("=== PWA Install Debug ===");
        // console.log("deferredPrompt:", deferredPrompt);
        // console.log("globalDeferredPrompt:", getGlobalDeferredPrompt());
        // console.log("isPWA():", isPWA());
        // console.log("isMobile():", isMobile());
        // console.log("isPWAInstallSupported():", isPWAInstallSupported());
        // console.log("Service Worker supported:", "serviceWorker" in navigator);
        // console.log(
        //   "HTTPS:",
        //   window.location.protocol === "https:" || window.location.hostname === "localhost"
        // );
        // console.log("========================");
      };
    }
  }, [deferredPrompt]);

  // iOS Instructions Component
  const IOSInstructions = () => (
    <div className="pwa-overlay__ios-instructions">
      <div className="pwa-overlay__ios-steps">
        <div className="pwa-overlay__ios-step">
          <div className="step-number">1</div>
          <div className="step-content">
            <p>
            Tap the share button
              <Image src={tapShare} alt="share icon" width="20" height="20" />sometimes found through<svg className="inline" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M6.23047 13.5C5.81797 13.5 5.46489 13.3531 5.17122 13.0592C4.87739 12.7656 4.73047 12.4125 4.73047 12C4.73047 11.5875 4.87739 11.2344 5.17122 10.9408C5.46489 10.6469 5.81797 10.5 6.23047 10.5C6.64297 10.5 6.99614 10.6469 7.28997 10.9408C7.58364 11.2344 7.73047 11.5875 7.73047 12C7.73047 12.4125 7.58364 12.7656 7.28997 13.0592C6.99614 13.3531 6.64297 13.5 6.23047 13.5ZM11.9997 13.5C11.5872 13.5 11.2341 13.3531 10.9405 13.0592C10.6466 12.7656 10.4997 12.4125 10.4997 12C10.4997 11.5875 10.6466 11.2344 10.9405 10.9408C11.2341 10.6469 11.5872 10.5 11.9997 10.5C12.4122 10.5 12.7653 10.6469 13.059 10.9408C13.3528 11.2344 13.4997 11.5875 13.4997 12C13.4997 12.4125 13.3528 12.7656 13.059 13.0592C12.7653 13.3531 12.4122 13.5 11.9997 13.5ZM17.769 13.5C17.3565 13.5 17.0033 13.3531 16.7095 13.0592C16.4158 12.7656 16.269 12.4125 16.269 12C16.269 11.5875 16.4158 11.2344 16.7095 10.9408C17.0033 10.6469 17.3565 10.5 17.769 10.5C18.1815 10.5 18.5346 10.6469 18.8282 10.9408C19.1221 11.2344 19.269 11.5875 19.269 12C19.269 12.4125 19.1221 12.7656 18.8282 13.0592C18.5346 13.3531 18.1815 13.5 17.769 13.5Z" fill="#E30613"/>
</svg>
            </p>
          </div>
        </div>

        <div className="pwa-overlay__ios-step">
          <div className="step-number">2</div>
          <div className="step-content">
            <p>
              Scroll down and tap <strong>Add to Home Screen</strong>
            </p>
          </div>
        </div>

        <div className="pwa-overlay__ios-step">
          <div className="step-number">3</div>
          <div className="step-content">
            <p>
              Tap <strong>Add</strong> and now open it from your home screen
            </p>
          </div>
        </div>
      </div>
    </div>
  );

  return (
    <div className="pwa-overlay">
      <div className="pwa-overlay__wrapper">
        {/* Close button */}
        <div className="pwa-overlay-close">
          <button onClick={onDismiss} className="pwa-overlay__close" aria-label="Dismiss">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="18"
              height="18"
              viewBox="0 0 18 18"
              fill="none"
            >
              <path
                d="M9.00038 9.79032L5.19562 13.5953C5.09175 13.699 4.96119 13.7521 4.80394 13.7546C4.64681 13.757 4.51388 13.7039 4.40513 13.5953C4.2965 13.4865 4.24219 13.3548 4.24219 13.2C4.24219 13.0453 4.2965 12.9135 4.40513 12.8048L8.21006 9.00001L4.40513 5.19526C4.30138 5.09138 4.24825 4.96082 4.24575 4.80357C4.24338 4.64645 4.2965 4.51351 4.40513 4.40476C4.51388 4.29613 4.64563 4.24182 4.80038 4.24182C4.95513 4.24182 5.08687 4.29613 5.19562 4.40476L9.00038 8.2097L12.8051 4.40476C12.909 4.30101 13.0396 4.24788 13.1968 4.24538C13.3539 4.24301 13.4869 4.29613 13.5956 4.40476C13.7043 4.51351 13.7586 4.64526 13.7586 4.80001C13.7586 4.95476 13.7043 5.08651 13.5956 5.19526L9.79069 9.00001L13.5956 12.8048C13.6994 12.9086 13.7525 13.0392 13.755 13.1964C13.7574 13.3536 13.7043 13.4865 13.5956 13.5953C13.4869 13.7039 13.3551 13.7582 13.2004 13.7582C13.0456 13.7582 12.9139 13.7039 12.8051 13.5953L9.00038 9.79032Z"
                fill="#B8B8B8"
              />
            </svg>{" "}
            <span className="text">No thanks</span>
          </button>
        </div>

        {/* Common content for both iOS and Android */}
        <div className="pwa-overlay__content">
          <div className="pwa-overlay__icon">
            <Image src={pwaInstallIcon} alt="pwa install icon" width="60" height="60" />
          </div>
          <div className="pwa-overlay__description">
            <h3>Easy access, always at hand</h3>

            {/* Description */}
            <p className="text-sm text-gray-600 text-center mb-6">
              Add the SITE-SECURITY Customer Portal to your phone's home screen for easy access and <span className="red-text">critical real-time updates</span> about your solution.
            </p>
          </div>

          {/* Show iOS instructions or Android button */}
          {isIOSDevice() ? (
            <IOSInstructions />
          ) : (
            <div className="pwa-overlay__btn">
              <button
                onClick={handleInstall}
                disabled={isInstalling}
                className="pwa-overlay__button"
              >
                {isInstalling ? (
                  "Installing..."
                ) : (
                  <>
                    <span className="icon-text install-btn">
                      <Image src={homeScreenButton} alt="tap share" width="12" height="12" />
                      Add to home screen
                    </span>
                  </>
                )}
              </button>
            </div>
          )}
        </div>

        {/* Instructions */}

        {/* Action buttons */}
        {/* <div className="flex flex-col space-y-3">
        
          <button
            onClick={onDismiss}
            className="w-full text-gray-600 py-2 px-4 rounded-lg font-medium hover:bg-gray-100 transition-colors"
          >
            Dismiss
          </button>
        </div> */}
      </div>
    </div>
  );
};

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists