Skip to content

Commit 384c0c8

Browse files
feat: updated download card
1 parent a1eabf6 commit 384c0c8

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

app/(course)/(routes)/courses/[courseId]/chapters/[chapterId]/page.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { File } from 'lucide-react';
2-
import Link from 'next/link';
31
import { redirect } from 'next/navigation';
42

53
import { getCurrentUser } from '@/actions/auth/get-current-user';
64
import { getChapter } from '@/actions/courses/get-chapter';
75
import { Banner } from '@/components/common/banner';
6+
import { FileDownload } from '@/components/common/file-download';
87
import { Preview } from '@/components/common/preview';
98
import { Separator } from '@/components/ui/separator';
109

@@ -84,16 +83,8 @@ const ChapterIdPage = async ({ params }: ChapterIdPageProps) => {
8483
<>
8584
<Separator />
8685
<div className="p-4">
87-
{attachments.map((attachment) => (
88-
<Link
89-
className="flex items-center p-3 w-full rounded-md bg-blue-500/15 border border-blue-500/20 text-blue-700 dark:text-blue-400 mb-2"
90-
key={attachment.id}
91-
target="_blank"
92-
href={attachment.url}
93-
>
94-
<File className="h-4 w-4 mr-2 flex-shrink-0" />
95-
<p className="text-sm line-clamp-1 basis-4/5">{attachment.name}</p>
96-
</Link>
86+
{attachments.map(({ id, url, name: fileName }) => (
87+
<FileDownload key={id} fileName={fileName} url={url} />
9788
))}
9889
</div>
9990
</>

app/(dashboard)/(routes)/teacher/courses/[courseId]/_components/form/attachment-form.tsx

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
'use client';
22

33
import { Attachment, Course } from '@prisma/client';
4-
import { File, Paperclip, X } from 'lucide-react';
5-
import Link from 'next/link';
4+
import { Paperclip } from 'lucide-react';
65
import { useRouter } from 'next/navigation';
76
import { useState } from 'react';
87
import toast from 'react-hot-toast';
9-
import { BiLoaderAlt } from 'react-icons/bi';
108
import * as z from 'zod';
119

10+
import { FileDownload } from '@/components/common/file-download';
1211
import { FileUpload } from '@/components/common/file-upload';
1312
import { Button } from '@/components/ui/button';
1413
import { fetcher } from '@/lib/fetcher';
@@ -77,34 +76,15 @@ export const AttachmentForm = ({ initialData, courseId }: AttachmentProps) => {
7776
{initialData.attachments.length > 0 ? (
7877
<div className="space-y-2 mt-4">
7978
{initialData.attachments.map((attachment) => (
80-
<div
79+
<FileDownload
8180
key={attachment.id}
82-
className="flex items-center p-3 w-full rounded-md bg-blue-500/15 border border-blue-500/20 text-blue-700 dark:text-blue-400"
83-
>
84-
<File className="h-4 w-4 mr-2 flex-shrink-0" />
85-
<Link
86-
className="text-sm line-clamp-1 basis-4/5 hover:underline"
87-
href={attachment.url}
88-
target="_blank"
89-
>
90-
{attachment.name}
91-
</Link>
92-
<div className="ml-auto flex items-center">
93-
{deletingId === attachment.id ? (
94-
<BiLoaderAlt className="h-4 w-4 animate-spin" />
95-
) : (
96-
<button
97-
className="hover:opacity-75 transition-all duration-300"
98-
onClick={() =>
99-
handleDelete(attachment.id, attachment?.url?.split('/')?.pop() ?? '')
100-
}
101-
disabled={Boolean(deletingId)}
102-
>
103-
<X className="h-4 w-4" />
104-
</button>
105-
)}
106-
</div>
107-
</div>
81+
fileName={attachment.name}
82+
isRemoveButtonDisabled={deletingId === attachment.id}
83+
onFileRemove={() =>
84+
handleDelete(attachment.id, attachment?.url?.split('/')?.pop() ?? '')
85+
}
86+
url={attachment.url}
87+
/>
10888
))}
10989
</div>
11090
) : (
@@ -123,7 +103,7 @@ export const AttachmentForm = ({ initialData, courseId }: AttachmentProps) => {
123103
}}
124104
/>
125105
<div className="flex text-xs items-start justify-between">
126-
<div className="text-muted-foreground mt-4 basis-3/5">
106+
<div className="text-muted-foreground mt-4">
127107
Add anything your students might need to complete the course
128108
</div>
129109
</div>

components/common/file-download.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use client';
2+
3+
import { Download, FileText, Trash2 } from 'lucide-react';
4+
import Link from 'next/link';
5+
6+
import { Button } from '../ui';
7+
8+
type FileDownloadProps = {
9+
fileName: string;
10+
isRemoveButtonDisabled?: boolean;
11+
onFileRemove?: () => void;
12+
url: string;
13+
};
14+
15+
export const FileDownload = ({
16+
fileName,
17+
isRemoveButtonDisabled = false,
18+
onFileRemove,
19+
url,
20+
}: FileDownloadProps) => {
21+
const [name, extension] = fileName.split('.');
22+
23+
return (
24+
<div className="flex items-center justify-between p-3 w-full rounded-md border mb-2">
25+
<div className="flex items-center">
26+
<FileText className="h-4 w-4 mr-3 flex-shrink-0 text-red-500" />
27+
<div className="flex flex-col">
28+
<p className="text-primary font-medium text-sm">{name}</p>
29+
<p className="text-muted-foreground text-xs">{`.${extension}`}</p>
30+
</div>
31+
</div>
32+
<div className="flex items-center gap-x-2">
33+
<Link href={url} target="_blank">
34+
<Button variant="outline" title="Download">
35+
<Download className="h-4 w-4" />
36+
</Button>
37+
</Link>
38+
{Boolean(onFileRemove) && (
39+
<Button
40+
variant="outline"
41+
disabled={isRemoveButtonDisabled}
42+
onClick={onFileRemove!}
43+
title="Remove"
44+
>
45+
<Trash2 className="h-4 w-4" />
46+
</Button>
47+
)}
48+
</div>
49+
</div>
50+
);
51+
};

0 commit comments

Comments
 (0)