Files
honeyDueWeb/src/components/sharing/share-code-display.tsx
T
Trey t 7884ebbfd4 feat: Phase 4-5 — demo mode, polish, deploy, and bug fixes
Add demo mode with mock data provider, Docker deployment, Playwright
tests, PostHog analytics, error boundaries, and SEO metadata. Fix
residences API response unwrapping, kanban drag-and-drop with optimistic
updates, trailing slash proxy redirects, and column name mismatches with
Go API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:37:41 -06:00

116 lines
3.5 KiB
TypeScript

"use client";
import { useState } from "react";
import { toast } from "sonner";
import { Copy, Check, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useShareCode, useGenerateShareCode } from "@/lib/hooks/use-sharing";
interface ShareCodeDisplayProps {
residenceId: number;
}
export function ShareCodeDisplay({ residenceId }: ShareCodeDisplayProps) {
const { data, isLoading } = useShareCode(residenceId);
const generateCode = useGenerateShareCode(residenceId);
const [copied, setCopied] = useState(false);
const shareCode = data?.share_code;
async function handleCopy() {
if (!shareCode) return;
await navigator.clipboard.writeText(shareCode.code);
setCopied(true);
toast.success("Code copied to clipboard");
setTimeout(() => setCopied(false), 2000);
}
function handleGenerate() {
generateCode.mutate(undefined, {
onSuccess: () => {
toast.success("Share code generated");
},
onError: () => {
toast.error("Failed to generate share code");
},
});
}
if (isLoading) {
return (
<Card>
<CardHeader>
<CardTitle>Share Code</CardTitle>
<CardDescription>Loading...</CardDescription>
</CardHeader>
</Card>
);
}
return (
<Card>
<CardHeader>
<CardTitle>Share Code</CardTitle>
<CardDescription>
Share this code with others to invite them to your residence.
</CardDescription>
</CardHeader>
<CardContent>
{shareCode ? (
<div className="space-y-4">
<div className="flex items-center gap-3">
<code className="flex-1 rounded-lg border bg-muted px-4 py-3 text-center text-2xl font-mono font-bold tracking-widest">
{shareCode.code}
</code>
<Button
variant="outline"
size="icon"
onClick={handleCopy}
title="Copy to clipboard"
>
{copied ? (
<Check className="size-4 text-green-600" />
) : (
<Copy className="size-4" />
)}
</Button>
</div>
<p className="text-sm text-muted-foreground">
Expires{" "}
{new Date(shareCode.expires_at).toLocaleDateString(undefined, {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "2-digit",
})}
</p>
<Button
variant="outline"
size="sm"
onClick={handleGenerate}
disabled={generateCode.isPending}
>
<RefreshCw className="size-4 mr-2" />
{generateCode.isPending ? "Generating..." : "Generate New Code"}
</Button>
</div>
) : (
<div className="text-center py-4">
<p className="text-sm text-muted-foreground mb-4">
No active share code. Generate one to invite others.
</p>
<Button
onClick={handleGenerate}
disabled={generateCode.isPending}
>
{generateCode.isPending ? "Generating..." : "Generate Share Code"}
</Button>
</div>
)}
</CardContent>
</Card>
);
}