Skip to content

Commit

Permalink
feat: add new view page for viewing custom domain document links
Browse files Browse the repository at this point in the history
  • Loading branch information
mfts committed Aug 24, 2023
1 parent 2d34175 commit 8518d5b
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 1 deletion.
7 changes: 6 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ NEXT_PUBLIC_BASE_URL=http://localhost:3000
RESEND_API_KEY=

# This variable is from Tinybird to publish and read event data
TINYBIRD_TOKEN=
TINYBIRD_TOKEN=

# These variables are from Vercel and used for setting up custom domains
PROJECT_ID_VERCEL=
TEAM_ID_VERCEL=
AUTH_BEARER_TOKEN=
23 changes: 23 additions & 0 deletions lib/swr/use-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ export function useLink() {
};
}

export function useDomainLink() {
const router = useRouter();

const { domain, slug } = router.query as {
domain: string;
slug: string;
};

const { data: link, error } = useSWR<LinkWithDocument>(
domain && slug && `/api/links/domains/${encodeURIComponent(domain)}/${encodeURIComponent(slug)}`,
fetcher,
{
dedupingInterval: 10000,
}
);

return {
link,
loading: !error && !link,
error,
};
}

interface ViewWithDuration extends View {
duration: {
data: { pageNumber: string; sum_duration: number }[];
Expand Down
12 changes: 12 additions & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ export const config = {

export default async function middleware(req: NextRequest, ev: NextFetchEvent) {
const path = req.nextUrl.pathname;
const host = req.headers.get('host');
const url = req.nextUrl.clone();

if (
process.env.NODE_ENV !== "development" &&
!(host?.includes("papermark.io") || host?.endsWith(".vercel.app"))
) {
// Subdomain available, rewriting
console.log(`>>> Rewriting: ${path} to /view/domains/${host}${path}`);
url.pathname = `/view/domains/${host}${path}`;
return NextResponse.rewrite(url);
}

if (path !== "/" && path !== "/alternatives/docsend") {
return AppMiddleware(req);
Expand Down
91 changes: 91 additions & 0 deletions pages/view/domains/[domain]/[slug]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { useState } from "react";
import EmailForm from "@/components/EmailForm";
import { classNames, getExtension } from "@/lib/utils";
import { useDomainLink } from "@/lib/swr/use-link";
import ErrorPage from "next/error";
import PDFViewer from "@/components/PDFViewer";
import { set } from "date-fns";

export default function DocumentView() {
const { link, error } = useDomainLink();
const [email, setEmail] = useState("");
const [submitted, setSubmitted] = useState(false);
const [viewId, setViewId] = useState<string>("");

if (error && error.status === 404) {
return <ErrorPage statusCode={404} />;
}

if (!link) {
return <div>Loading...</div>;
}
const { document } = link;

const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();

const response = await fetch("/api/views", {
method: "POST",
body: JSON.stringify({ linkId: link.id, email, documentId: document.id }),
headers: {
"Content-Type": "application/json",
},
});

if (response.ok) {
const { viewId } = await response.json();
setViewId(viewId);
setSubmitted(true);
} else {
// Handle error
}
};

if (!submitted) {
return <EmailForm onSubmitHandler={handleSubmit} setEmail={setEmail} />;
}

// get the file extension
const extension = getExtension(document.file);

if (
extension.includes(".docx") ||
extension.includes(".pptx") ||
extension.includes(".xlsx") ||
extension.includes(".xls") ||
extension.includes(".doc") ||
extension.includes(".ppt")
) {
return (
<div className="h-screen bg-gray-900">
<iframe
className="w-full h-full"
src={`https://view.officeapps.live.com/op/embed.aspx?src=${document.file}`}
></iframe>
</div>
);
}

if (
extension.includes(".png") ||
extension.includes(".jpeg") ||
extension.includes(".gif") ||
extension.includes(".jpg")
) {
return (
<div className="h-screen bg-gray-900">
<img className="w-full h-full" src={document.file} />
</div>
);
}
return (
<div className="bg-gray-950">
<PDFViewer
file={document.file}
viewId={viewId}
linkId={link.id}
documentId={document.id}
/>
</div>
);
}

0 comments on commit 8518d5b

Please sign in to comment.