Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions app/dashboard/LinkIdCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@ import { Copy, Check, ExternalLink, Link2 } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";

export function LinkIdCard({ username, qrCode }: { username: string; qrCode?: React.ReactNode }) {
export function LinkIdCard({
username,
qrCode,
}: {
username: string;
qrCode?: React.ReactNode;
}) {
const [copied, setCopied] = useState(false);

function copyProfile() {
navigator.clipboard.writeText(`linkid.qzz.io/${username}`);
setCopied(true);
toast.success("Profile link copied successfully!");
setTimeout(() => setCopied(false), 1200);
async function copyProfile() {
try {
await navigator.clipboard.writeText(`https://linkid.qzz.io/${username}`);
setCopied(true);
toast.success("Profile link copied successfully!");
setTimeout(() => setCopied(false), 1200);
} catch (error) {
toast.error("Unable to copy profile link. Please try again.");
}
}

return (
Expand All @@ -21,23 +31,21 @@ export function LinkIdCard({ username, qrCode }: { username: string; qrCode?: Re
<Link2 className="h-4 w-4 sm:h-5 sm:w-5" />
Your LinkID
</CardTitle>
<div className="flex-shrink-0">
{qrCode}
</div>
<div className="flex-shrink-0">{qrCode}</div>
</CardHeader>

<CardContent className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
{/* Link box */}
<div className="flex items-center justify-between gap-2 rounded-md bg-muted px-3 py-2 text-sm font-mono w-full sm:w-auto">
<code className="truncate">
linkid.qzz.io/{username}
</code>
<code className="truncate">linkid.qzz.io/{username}</code>

<Button
size="icon"
variant="ghost"
onClick={copyProfile}
className="shrink-0"
aria-label="Copy profile link"
title="Copy profile link"
>
{copied ? (
<Check className="h-4 w-4 text-green-600" />
Expand Down
89 changes: 55 additions & 34 deletions app/dashboard/LinkItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export function LinkItem({
toast.success("Copied");
setTimeout(() => setCopied(false), 1200);
}
}

async function save() {
const validation = validateUrl(url);
Expand All @@ -118,13 +119,13 @@ export function LinkItem({
}
}

return (
<div className="rounded-md border p-4 space-y-4">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="flex gap-3 items-center min-w-0">
<div className="h-10 w-10 bg-muted rounded-md flex items-center justify-center shrink-0">
<Icon className="h-5 w-5" />
</div>
return (
<div className="rounded-md border p-4 space-y-4">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="flex gap-3 items-center min-w-0">
<div className="h-10 w-10 bg-muted rounded-md flex items-center justify-center shrink-0">
<Icon className="h-5 w-5" />
</div>

<div className="min-w-0">
<p className="font-medium capitalize">
Expand Down Expand Up @@ -159,34 +160,52 @@ export function LinkItem({
</div>
</div>

<div className="flex flex-wrap gap-1 justify-end">
<Button
size="icon"
variant="ghost"
onClick={() => onToggleVisibility(link.id, !link.isPublic)}
aria-label={link.isPublic ? "Make link private" : "Make link public"}
title={link.isPublic ? "Make link private" : "Make link public"}
>
{link.isPublic ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
</Button>
<div className="flex flex-wrap gap-1 justify-end">
<Button
size="icon"
variant="ghost"
onClick={() => onToggleVisibility(link.id, !link.isPublic)}
aria-label={
link.isPublic ? "Make link private" : "Make link public"
}
title={link.isPublic ? "Make link private" : "Make link public"}
>
{link.isPublic ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
</Button>

<Button size="icon" variant="ghost" onClick={copy}>
{copied ? (
<Check className="h-4 w-4 text-green-600" />
) : (
<Copy className="h-4 w-4" />
)}
</Button>
<Button
size="icon"
variant="ghost"
onClick={copy}
aria-label="Copy link"
title="Copy link"
>
{copied ? (
<Check className="h-4 w-4 text-green-600" />
) : (
<Copy className="h-4 w-4" />
)}
</Button>

<a href={link.url} target="_blank" rel="noopener noreferrer" aria-label={`Open ${link.label ?? link.platform} in new tab`}>
<Button size="icon" variant="ghost" title={`Open ${link.label ?? link.platform}`}>
<ExternalLink className="h-4 w-4" />
</Button>
</a>
<Button
asChild
size="icon"
variant="ghost"
title={`Open ${link.label ?? link.platform}`}
>
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
aria-label={`Open ${link.label ?? link.platform} in new tab`}
>
<ExternalLink className="h-4 w-4" />
</a>
</Button>

<Button
size="icon"
Expand Down Expand Up @@ -301,5 +320,7 @@ export function LinkItem({
</div>
)}
</div>
);
)}
</div>
);
}
Empty file added dev.db
Empty file.
Loading