Untitled

 avatar
unknown
plain_text
2 months ago
11 kB
4
Indexable
import React, { useState, useEffect } from 'react';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { CheckCircle, Copy, Eye, EyeOff, Link, Lock, Share2, ExternalLink, X, Check, Loader2 } from "lucide-react";
import { toast } from "sonner";

interface ShareDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  favoriteCount: number;
  clientId: string;
  handleCreateSharedLink: (password: string, requirePassword: boolean) => Promise<string>;
}

export function ShareDialog({ 
  open, 
  onOpenChange, 
  favoriteCount,
  clientId,
  handleCreateSharedLink 
}: ShareDialogProps) {
  const [password, setPassword] = useState("");
  const [requirePassword, setRequirePassword] = useState(true);
  const [shareLink, setShareLink] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirmation, setShowConfirmation] = useState(false);
  const [copyIconState, setCopyIconState] = useState<'copy' | 'success' | 'error'>('copy');
  const [processingLink, setProcessingLink] = useState(false);
  
  // Reset copy icon state after animation
  useEffect(() => {
    if (copyIconState !== 'copy') {
      const timer = setTimeout(() => {
        setCopyIconState('copy');
      }, 2000);
      return () => clearTimeout(timer);
    }
  }, [copyIconState]);
  
  const resetState = () => {
    setPassword("");
    setRequirePassword(true);
    setShareLink("");
    setShowPassword(false);
    setShowConfirmation(false);
    setIsLoading(false);
    setCopyIconState('copy');
    setProcessingLink(false);
  };
  
  const handleClose = () => {
    resetState();
    onOpenChange(false);
  };
  
  const handleCreate = async () => {
    setShowConfirmation(true);
  };
  
  const handleConfirm = async () => {
    try {
      setIsLoading(true);
      setShowConfirmation(false);
      setProcessingLink(true); // Show the processing overlay
      
      const link = await handleCreateSharedLink(password, requirePassword);
      setShareLink(link);
    } catch (error) {
      console.error("Error creating shared link:", error);
      toast.error("Fehler beim Erstellen des Links.");
    } finally {
      setIsLoading(false);
      setProcessingLink(false); // Hide the processing overlay
    }
  };
  
  const copyToClipboard = () => {
    navigator.clipboard.writeText(shareLink)
      .then(() => {
        toast.success("Link in die Zwischenablage kopiert!");
        setCopyIconState('success');
      })
      .catch(() => {
        toast.error("Fehler beim Kopieren des Links.");
        setCopyIconState('error');
      });
  };
  
  const openLinkInNewTab = () => {
    window.open(shareLink, '_blank');
  };
  
  return (
    <>
      {/* Confirmation Dialog */}
      <AlertDialog open={showConfirmation} onOpenChange={setShowConfirmation}>
        <AlertDialogContent className="bg-zinc-900 border-zinc-800 text-zinc-100">
          <AlertDialogHeader>
            <AlertDialogTitle className="flex items-center gap-2">
              <Share2 className="h-5 w-5 text-blue-500" /> 
              Favoriten teilen bestätigen
            </AlertDialogTitle>
            <AlertDialogDescription className="text-zinc-400">
              Sie teilen {favoriteCount} {favoriteCount === 1 ? 'Bild' : 'Bilder'} 
              {requirePassword ? (
                <> mit Passwortschutz: <span className="font-medium text-zinc-300">{password}</span></>
              ) : (
                <> ohne Passwortschutz</>
              )}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel className="bg-zinc-800 text-zinc-300 hover:bg-zinc-700 hover:text-zinc-100 border-zinc-700">
              Abbrechen
            </AlertDialogCancel>
            <AlertDialogAction 
              className="bg-blue-600 hover:bg-blue-700 text-white border-0"
              onClick={handleConfirm}
              disabled={isLoading}
            >
              {isLoading ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Wird erstellt...
                </>
              ) : (
                "Link erstellen"
              )}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Main Share Dialog */}
      <Dialog open={open} onOpenChange={handleClose}>
        <DialogContent className="bg-zinc-900 border-zinc-800 text-zinc-100 sm:max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Share2 className="h-5 w-5 text-blue-500" />
              Favoriten teilen
            </DialogTitle>
            <DialogDescription className="text-zinc-400">
              Erstellen Sie einen Link, um Ihre {favoriteCount} ausgewählten Bilder zu teilen.
            </DialogDescription>
          </DialogHeader>
          
          {/* Processing Link Overlay */}
          {processingLink && (
            <div className="absolute inset-0 bg-zinc-900/90 backdrop-blur-sm flex flex-col items-center justify-center z-50 rounded-md">
              <div className="bg-indigo-500/10 p-4 rounded-full mb-4">
                <Loader2 className="h-8 w-8 text-indigo-400 animate-spin" />
              </div>
              <h3 className="text-lg font-medium mb-2 text-zinc-200">Link wird erstellt</h3>
              <p className="text-zinc-400 text-center max-w-xs">
                Bitte warten Sie, während Ihr persönlicher Link generiert wird...
              </p>
            </div>
          )}
          
          {shareLink ? (
            <div className="space-y-4 py-2">
              <div className="bg-zinc-800/50 p-3 rounded-md flex items-center gap-2 border border-zinc-700">
                <CheckCircle className="h-5 w-5 text-green-500 flex-shrink-0" />
                <p className="text-sm text-zinc-300">
                  Link wurde erfolgreich erstellt!
                </p>
              </div>
              
              <div className="flex items-center space-x-2">
                <div className="bg-zinc-800 flex-1 rounded-md flex items-center overflow-hidden">
                  <div className="bg-zinc-900/50 p-3">
                    <Link className="h-5 w-5 text-zinc-400" />
                  </div>
                  <input
                    className="flex-1 bg-transparent border-0 text-sm px-3 py-2 focus:outline-none text-zinc-300"
                    value={shareLink}
                    readOnly
                  />
                </div>
                <Button 
                  type="button" 
                  size="icon" 
                  onClick={copyToClipboard}
                  className={`transition-colors duration-300 ${
                    copyIconState === 'success' 
                      ? 'bg-green-600 hover:bg-green-700' 
                      : copyIconState === 'error'
                      ? 'bg-red-600 hover:bg-red-700'
                      : 'bg-blue-600 hover:bg-blue-700'
                  } text-white`}
                >
                  {copyIconState === 'copy' && <Copy className="h-4 w-4" />}
                  {copyIconState === 'success' && <Check className="h-4 w-4" />}
                  {copyIconState === 'error' && <X className="h-4 w-4" />}
                </Button>
              </div>
              
              <Button 
                type="button"
                onClick={openLinkInNewTab}
                className="w-full bg-zinc-800 hover:bg-zinc-700 text-zinc-300 flex items-center justify-center gap-2"
              >
                <ExternalLink className="h-4 w-4" />
                Link in neuem Tab öffnen
              </Button>
              
              <div className="pt-2">
                <Button 
                  onClick={handleClose}
                  className="w-full"
                >
                  Schließen
                </Button>
              </div>
            </div>
          ) : (
            <div className="space-y-4 py-2">
              <div className="space-y-4">
                <div className="flex items-center justify-between">
                  <Label htmlFor="require-password" className="text-zinc-300 flex items-center gap-2">
                    <Lock className="h-4 w-4 text-zinc-400" />
                    Passwortschutz
                  </Label>
                  <Switch
                    id="require-password"
                    checked={requirePassword}
                    onCheckedChange={setRequirePassword}
                  />
                </div>
                
                {requirePassword && (
                  <div className="space-y-2">
                    <Label htmlFor="password" className="text-zinc-300">
                      Passwort für den geteilten Link
                    </Label>
                    <div className="relative">
                      <Input
                        id="password"
                        type={showPassword ? "text" : "password"}
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        placeholder="Passwort eingeben"
                        className="bg-zinc-800 border-zinc-700 pr-10"
                      />
                      <button
                        type="button"
                        onClick={() => setShowPassword(!showPassword)}
                        className="absolute right-3 top-2.5 text-zinc-400 hover:text-zinc-300"
                      >
                        {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                      </button>
                    </div>
                  </div>
                )}
                
                <div className="pt-2">
                  <Button 
                    onClick={handleCreate}
                    disabled={requirePassword && !password}
                    className="w-full bg-gradient-to-r from-indigo-500 to-blue-500 hover:from-indigo-600 hover:to-blue-600 text-white border-0"
                  >
                    Link erstellen
                  </Button>
                </div>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
Editor is loading...
Leave a Comment