Untitled
unknown
plain_text
10 months ago
10 kB
12
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 } 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');
// 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');
};
const handleClose = () => {
resetState();
onOpenChange(false);
};
const handleCreate = async () => {
setShowConfirmation(true);
};
const handleConfirm = async () => {
try {
setIsLoading(true);
const link = await handleCreateSharedLink(password, requirePassword);
setShareLink(link);
setShowConfirmation(false);
} catch (error) {
console.error("Error creating shared link:", error);
toast.error("Fehler beim Erstellen des Links.");
} finally {
setIsLoading(false);
}
};
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 ? "Erstelle Link..." : "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>
{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