Skip to content

Commit beb09d9

Browse files
author
raineer
committed
ndaservice
1 parent ccf9481 commit beb09d9

4 files changed

Lines changed: 1144 additions & 661 deletions

File tree

‎apps/codebility/app/home/in-house/_components/table/InHouseTable.tsx‎

Lines changed: 126 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// app/home/in-house/_components/table/InHouseTable.tsx
12
"use client";
23

34
import { useCallback, useEffect, useMemo, useState } from "react";
@@ -85,9 +86,6 @@ const capitalize = (str: string) =>
8586

8687
/**
8788
* Converts display position to uppercase format
88-
* Input → Output Examples:
89-
* "frontend developer" → "FRONTEND DEVELOPER"
90-
* "ui/ux designer" → "UI/UX DESIGNER"
9189
* @param position - Display position string
9290
* @returns Uppercase position or dash for empty values
9391
*/
@@ -97,8 +95,8 @@ const formatDisplayPosition = (position: string | null | undefined): string => {
9795
};
9896

9997
/**
100-
* NDA Email Button Component
101-
* Handles sending NDA signing requests to team members
98+
* Enhanced NDA Email Button Component
99+
* Now integrates with the new storage-first NDA process
102100
*/
103101
const SendNdaButton = ({ codev, onSendNdaEmail }: NdaEmailDialogProps) => {
104102
const [isSending, setIsSending] = useState(false);
@@ -135,8 +133,8 @@ const SendNdaButton = ({ codev, onSendNdaEmail }: NdaEmailDialogProps) => {
135133
};
136134

137135
/**
138-
* Main InHouseTable Component
139-
* Displays team member data with responsive design and inline editing
136+
* Main InHouseTable Component with Enhanced NDA Storage Integration
137+
* Now properly handles NDA signature and document URLs from Supabase Storage
140138
*/
141139
export function InHouseTable({
142140
data,
@@ -188,8 +186,8 @@ export function InHouseTable({
188186
};
189187

190188
/**
191-
* Sends NDA signing request email to team member
192-
* Creates unique token and database record for tracking
189+
* Enhanced NDA email sending with proper database tracking
190+
* Now creates NDA request records and generates secure tokens
193191
*/
194192
const handleSendNdaEmail = async (
195193
codevId: string,
@@ -250,33 +248,98 @@ export function InHouseTable({
250248
};
251249

252250
/**
253-
* Downloads NDA document for signed members
251+
* Enhanced NDA document download function
252+
* Now downloads from Supabase Storage URLs instead of base64 data
254253
* @param codevId - ID of the member whose NDA to download
255254
*/
256255
const handleDownloadNda = async (codevId: string) => {
257256
try {
258257
const { data, error } = await supabase
259258
.from("codev")
260-
.select("nda_document, first_name, last_name")
259+
.select("nda_document, nda_signature, first_name, last_name")
261260
.eq("id", codevId)
262261
.single();
263262

264-
if (error || !data || !data.nda_document) {
265-
throw new Error("Failed to fetch NDA document");
263+
if (error || !data) {
264+
throw new Error("Failed to fetch member data");
266265
}
267266

267+
// Check if NDA document URL exists
268+
if (!data.nda_document) {
269+
throw new Error("No signed NDA document found for this member");
270+
}
271+
272+
// Download the document directly from the storage URL
273+
const response = await fetch(data.nda_document);
274+
if (!response.ok) {
275+
throw new Error("Failed to download NDA document");
276+
}
277+
278+
const blob = await response.blob();
279+
268280
// Create download link and trigger download
281+
const url = window.URL.createObjectURL(blob);
269282
const link = document.createElement("a");
270-
link.href = data.nda_document;
283+
link.href = url;
271284
link.download = `NDA_${data.first_name}_${data.last_name}.pdf`;
272285
document.body.appendChild(link);
273286
link.click();
287+
288+
// Cleanup
274289
document.body.removeChild(link);
290+
window.URL.revokeObjectURL(url);
275291

276292
toast.success("NDA document downloaded successfully");
277293
} catch (error) {
278294
console.error("Error downloading NDA:", error);
279-
toast.error("Failed to download NDA document");
295+
toast.error(
296+
error instanceof Error
297+
? error.message
298+
: "Failed to download NDA document"
299+
);
300+
}
301+
};
302+
303+
/**
304+
* Downloads NDA signature image separately
305+
* @param codevId - ID of the member whose signature to download
306+
*/
307+
const handleDownloadSignature = async (codevId: string) => {
308+
try {
309+
const { data, error } = await supabase
310+
.from("codev")
311+
.select("nda_signature, first_name, last_name")
312+
.eq("id", codevId)
313+
.single();
314+
315+
if (error || !data || !data.nda_signature) {
316+
throw new Error("No signature found for this member");
317+
}
318+
319+
// Download the signature directly from the storage URL
320+
const response = await fetch(data.nda_signature);
321+
if (!response.ok) {
322+
throw new Error("Failed to download signature");
323+
}
324+
325+
const blob = await response.blob();
326+
327+
// Create download link and trigger download
328+
const url = window.URL.createObjectURL(blob);
329+
const link = document.createElement("a");
330+
link.href = url;
331+
link.download = `Signature_${data.first_name}_${data.last_name}.png`;
332+
document.body.appendChild(link);
333+
link.click();
334+
335+
// Cleanup
336+
document.body.removeChild(link);
337+
window.URL.revokeObjectURL(url);
338+
339+
toast.success("Signature downloaded successfully");
340+
} catch (error) {
341+
console.error("Error downloading signature:", error);
342+
toast.error("Failed to download signature");
280343
}
281344
};
282345

@@ -291,7 +354,6 @@ export function InHouseTable({
291354

292355
/**
293356
* Advanced pagination handler for direct page navigation
294-
* Implements step-by-step navigation since direct page setting isn't available
295357
*/
296358
const setCurrentPage = useCallback((pageOrFunction: number | ((page: number) => number)) => {
297359
const page =
@@ -464,7 +526,7 @@ export function InHouseTable({
464526
</DropdownMenuPortal>
465527
</DropdownMenuSub>
466528

467-
{/* NDA Status submenu with action buttons */}
529+
{/* Enhanced NDA Status submenu with storage-based actions */}
468530
<DropdownMenuSub>
469531
<DropdownMenuSubTrigger>
470532
NDA Status
@@ -476,17 +538,28 @@ export function InHouseTable({
476538
{item.nda_status ? "Yes" : "No"}
477539
</span>
478540

479-
{/* Conditional NDA action buttons */}
541+
{/* Enhanced NDA action buttons */}
480542
{item.nda_status ? (
481-
<Button
482-
variant="outline"
483-
size="sm"
484-
className="ml-2 text-green-500 hover:text-green-600 dark:text-green-200 dark:hover:text-green-300"
485-
onClick={() => handleDownloadNda(item.id)}
486-
>
487-
<Download className="mr-1 h-4 w-4" />
488-
Download
489-
</Button>
543+
<div className="flex gap-1">
544+
<Button
545+
variant="outline"
546+
size="sm"
547+
className="text-green-500 hover:text-green-600 dark:text-green-200 dark:hover:text-green-300"
548+
onClick={() => handleDownloadNda(item.id)}
549+
>
550+
<Download className="mr-1 h-3 w-3" />
551+
PDF
552+
</Button>
553+
<Button
554+
variant="outline"
555+
size="sm"
556+
className="text-blue-500 hover:text-blue-600 dark:text-blue-200 dark:hover:text-blue-300"
557+
onClick={() => handleDownloadSignature(item.id)}
558+
>
559+
<Download className="mr-1 h-3 w-3" />
560+
Sig
561+
</Button>
562+
</div>
490563
) : item.nda_request_sent ? (
491564
<Button
492565
variant="outline"
@@ -606,24 +679,37 @@ export function InHouseTable({
606679
)}
607680
</TableCell>
608681

609-
{/* NDA Status column with action buttons */}
682+
{/* Enhanced NDA Status column with storage-based action buttons */}
610683
<TableCell className="dark:text-light-900 hidden px-2 py-2 text-base text-black 2xl:table-cell">
611684
<div className="flex items-center gap-2">
612685
<span className={`${getNdaStatusColor(item.nda_status)}`}>
613686
{item.nda_status ? "Yes" : "No"}
614687
</span>
615688

616-
{/* Conditional NDA action buttons */}
689+
{/* Enhanced NDA action buttons with dual download options */}
617690
{item.nda_status ? (
618-
<Button
619-
variant="outline"
620-
size="sm"
621-
className="ml-2 text-green-500 hover:text-green-600 dark:text-green-200 dark:hover:text-green-300"
622-
onClick={() => handleDownloadNda(item.id)}
623-
>
624-
<Download className="mr-1 h-4 w-4" />
625-
Download
626-
</Button>
691+
<div className="flex gap-1">
692+
<Button
693+
variant="outline"
694+
size="sm"
695+
className="text-green-500 hover:text-green-600 dark:text-green-200 dark:hover:text-green-300"
696+
onClick={() => handleDownloadNda(item.id)}
697+
title="Download NDA Document"
698+
>
699+
<Download className="mr-1 h-4 w-4" />
700+
PDF
701+
</Button>
702+
<Button
703+
variant="outline"
704+
size="sm"
705+
className="text-blue-500 hover:text-blue-600 dark:text-blue-200 dark:hover:text-blue-300"
706+
onClick={() => handleDownloadSignature(item.id)}
707+
title="Download Signature"
708+
>
709+
<Download className="mr-1 h-4 w-4" />
710+
Signature
711+
</Button>
712+
</div>
627713
) : item.nda_request_sent ? (
628714
<Button
629715
variant="outline"
@@ -691,9 +777,9 @@ export function InHouseTable({
691777
</Table>
692778
</div>
693779

694-
{/* Pagination Controls - Show when there are multiple pages */}
780+
{/* Pagination Controls - Only show when data exceeds page size */}
695781
<div className="relative w-full">
696-
{pagination.totalPages > 1 && (
782+
{data.length > pageSize.applicants && (
697783
<DefaultPagination
698784
currentPage={pagination.currentPage}
699785
handleNextPage={handleNextPage}

0 commit comments

Comments
 (0)