Skip to content

Commit

Permalink
Merge pull request #327 from captableinc/docs/viewer
Browse files Browse the repository at this point in the history
feat: implement office document viewer
  • Loading branch information
dahal committed May 17, 2024
2 parents 0cf3108 + a2d0608 commit 6c4c672
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 18 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
/node_modules
/.pnp
.pnp.js

# lockfiles
bun.lockb
package-lock.json
yarn.lock

# testing
/coverage
Expand Down
23 changes: 11 additions & 12 deletions src/components/common/file-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import { fileType } from "@/lib/mime";

import {
RiFileCloudFill,
Expand All @@ -16,54 +17,52 @@ type FileIconProps = {
};

const FileIcon = ({ type }: FileIconProps) => {
switch (true) {
case type.includes("image"):
const _type = fileType(type);

switch (_type) {
case "image":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-pink-100">
<RiFileImageFill className="h-5 w-5 text-pink-500" />
</div>
);

case type.includes("audio"):
case "audio":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-indigo-100">
<RiFileMusicFill className="h-5 w-5 text-indigo-500" />
</div>
);

case type.includes("video"):
case "video":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-rose-100">
<RiFileVideoFill className="h-5 w-5 text-rose-500" />
</div>
);

case type.includes("powerpoint") || type.includes("presentation"):
case "powerpoint":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-orange-100">
<RiFilePptFill className="h-5 w-5 text-orange-500" />
</div>
);

case type.includes("rtf"):
case type.includes("doc"):
case type.includes("word"):
case "doc":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-blue-100">
<RiFileWordFill className="h-5 w-5 text-blue-500" />
</div>
);

case type.includes("csv"):
case type.includes("excel"):
case type.includes("sheet"):
case "excel":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-emerald-100">
<RiFileExcelFill className="h-5 w-5 text-emerald-500" />
</div>
);

case type.includes("pdf"):
case "pdf":
return (
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-red-100">
<RiFilePdf2Fill className="h-5 w-5 text-red-500" />
Expand Down
16 changes: 16 additions & 0 deletions src/components/file/office-viewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
type OfficeViewerProps = {
url: string;
};

const OfficeViewer = ({ url }: OfficeViewerProps) => {
return (
<iframe
src={`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(
url,
)}`}
className="w-full h-full min-h-screen"
/>
);
};

export { OfficeViewer };
19 changes: 13 additions & 6 deletions src/components/file/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import EmptyState from "@/components/common/empty-state";
import { OfficeViewer } from "@/components/file/office-viewer";
import { Button } from "@/components/ui/button";
import { PdfViewer } from "@/components/ui/pdf-viewer";
import { fileType } from "@/lib/mime";
import { RiFileUnknowFill as UnknownFileIcon } from "@remixicon/react";

type FilePreviewProps = {
Expand Down Expand Up @@ -34,7 +36,7 @@ const VideoPreview = ({ url, name, mimeType }: FilePreviewProps) => {
const UnknownPreview = ({ url, name, mimeType }: FilePreviewProps) => {
return (
<EmptyState
title="File type not supported"
title="Preview not available"
subtitle={`This file type - ${mimeType} is not yet supported by the previewer. You can download the file by clicking the button below.`}
icon={<UnknownFileIcon />}
>
Expand All @@ -47,16 +49,21 @@ const UnknownPreview = ({ url, name, mimeType }: FilePreviewProps) => {

const FilePreview = ({ url, name, mimeType }: FilePreviewProps) => {
mimeType = mimeType || "";
const type = fileType(mimeType);

switch (true) {
case mimeType.includes("pdf"):
switch (type) {
case "pdf":
return <PdfViewer file={url} />;
case mimeType.startsWith("image"):
case "image":
return <ImagePreview url={url} name={name} />;
case mimeType.startsWith("audio"):
case "audio":
return <AuditPreview url={url} name={name} mimeType={mimeType} />;
case mimeType.startsWith("video"):
case "video":
return <VideoPreview url={url} name={name} mimeType={mimeType} />;
case "doc":
case "excel":
case "powerpoint":
return <OfficeViewer url={url} />;
default:
return <UnknownPreview url={url} name={name} mimeType={mimeType} />;
}
Expand Down
29 changes: 29 additions & 0 deletions src/lib/mime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
type FileProps = {
mimeType: string;
};

const fileType = (mimeType: string) => {
switch (true) {
case mimeType.includes("pdf"):
return "pdf";
case mimeType.includes("image"):
return "image";
case mimeType.includes("audio"):
return "audio";
case mimeType.includes("video"):
return "video";
case mimeType.includes("powerpoint") || mimeType.includes("presentation"):
return "powerpoint";
case mimeType.includes("csv") ||
mimeType.includes("excel") ||
mimeType.includes("sheet"):
return "excel";
case mimeType.includes("doc"):
case mimeType.includes("word"):
return "doc";
default:
return "unknown";
}
};

export { fileType };

0 comments on commit 6c4c672

Please sign in to comment.