diff --git a/packages/frontend/src/components/issue-detail-pane.tsx b/packages/frontend/src/components/issue-detail-pane.tsx
index 11af218..0eca03d 100644
--- a/packages/frontend/src/components/issue-detail-pane.tsx
+++ b/packages/frontend/src/components/issue-detail-pane.tsx
@@ -1,6 +1,6 @@
import type { IssueResponse, ProjectResponse, UserRecord } from "@issue/shared";
-import { Trash, X } from "lucide-react";
-import { useEffect, useState } from "react";
+import { Check, Link, Trash, X } from "lucide-react";
+import { useEffect, useRef, useState } from "react";
import { useSession } from "@/components/session-provider";
import SmallUserDisplay from "@/components/small-user-display";
import { StatusSelect } from "@/components/status-select";
@@ -36,12 +36,22 @@ export function IssueDetailPane({
);
const [status, setStatus] = useState(issueData.Issue.status);
const [deleteOpen, setDeleteOpen] = useState(false);
+ const [linkCopied, setLinkCopied] = useState(false);
+ const copyTimeoutRef = useRef(null);
useEffect(() => {
setAssigneeId(issueData.Issue.assigneeId?.toString() ?? "unassigned");
setStatus(issueData.Issue.status);
}, [issueData.Issue.assigneeId, issueData.Issue.status]);
+ useEffect(() => {
+ return () => {
+ if (copyTimeoutRef.current) {
+ window.clearTimeout(copyTimeoutRef.current);
+ }
+ };
+ }, []);
+
const handleAssigneeChange = async (value: string) => {
setAssigneeId(value);
const newAssigneeId = value === "unassigned" ? null : Number(value);
@@ -79,6 +89,22 @@ export function IssueDetailPane({
setDeleteOpen(true);
};
+ const handleCopyLink = async () => {
+ try {
+ await navigator.clipboard.writeText(window.location.href);
+ setLinkCopied(true);
+ if (copyTimeoutRef.current) {
+ window.clearTimeout(copyTimeoutRef.current);
+ }
+ copyTimeoutRef.current = window.setTimeout(() => {
+ setLinkCopied(false);
+ copyTimeoutRef.current = null;
+ }, 1500);
+ } catch (error) {
+ console.error("error copying issue link:", error);
+ }
+ };
+
const handleConfirmDelete = async () => {
await issue.delete({
issueId: issueData.Issue.id,
@@ -100,12 +126,19 @@ export function IssueDetailPane({
{issueID(project.Project.key, issueData.Issue.number)}
-
+
+