Compare commits
11 Commits
feat/add-d
...
feat/table
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ef3523d89 | ||
|
|
a27c6c3eb2 | ||
|
|
a5b3969f56 | ||
|
|
f61bf00702 | ||
|
|
86b0d5ee9c | ||
|
|
1dd1bb617d | ||
|
|
60b150cc58 | ||
|
|
bd0db0f8fd | ||
|
|
d8a094a324 | ||
|
|
4b063b68ab | ||
|
|
3c02331cb9 |
@@ -15,6 +15,7 @@ import {
|
|||||||
} from '@documenso/ui/primitives/table';
|
} from '@documenso/ui/primitives/table';
|
||||||
|
|
||||||
import { CardMetric } from '~/components/(dashboard)/metric-card/metric-card';
|
import { CardMetric } from '~/components/(dashboard)/metric-card/metric-card';
|
||||||
|
import { ActionButtons } from '~/components/(dashboard)/table/actions-component';
|
||||||
import { DocumentStatus } from '~/components/formatter/document-status';
|
import { DocumentStatus } from '~/components/formatter/document-status';
|
||||||
import { LocaleDate } from '~/components/formatter/locale-date';
|
import { LocaleDate } from '~/components/formatter/locale-date';
|
||||||
|
|
||||||
@@ -38,9 +39,15 @@ export default async function DashboardPage() {
|
|||||||
<h1 className="text-4xl font-semibold">Dashboard</h1>
|
<h1 className="text-4xl font-semibold">Dashboard</h1>
|
||||||
|
|
||||||
<div className="mt-8 grid grid-cols-1 gap-4 md:grid-cols-3">
|
<div className="mt-8 grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||||
|
<Link href={'/documents?status=COMPLETED'} passHref>
|
||||||
<CardMetric icon={FileCheck} title="Completed" value={stats.COMPLETED} />
|
<CardMetric icon={FileCheck} title="Completed" value={stats.COMPLETED} />
|
||||||
|
</Link>
|
||||||
|
<Link href={'/documents?status=DRAFT'} passHref>
|
||||||
<CardMetric icon={File} title="Drafts" value={stats.DRAFT} />
|
<CardMetric icon={File} title="Drafts" value={stats.DRAFT} />
|
||||||
|
</Link>
|
||||||
|
<Link href={'/documents?status=PENDING'} passHref>
|
||||||
<CardMetric icon={Clock} title="Pending" value={stats.PENDING} />
|
<CardMetric icon={Clock} title="Pending" value={stats.PENDING} />
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-12">
|
<div className="mt-12">
|
||||||
@@ -55,7 +62,8 @@ export default async function DashboardPage() {
|
|||||||
<TableHead className="w-[100px]">ID</TableHead>
|
<TableHead className="w-[100px]">ID</TableHead>
|
||||||
<TableHead>Title</TableHead>
|
<TableHead>Title</TableHead>
|
||||||
<TableHead>Status</TableHead>
|
<TableHead>Status</TableHead>
|
||||||
<TableHead className="text-right">Created</TableHead>
|
<TableHead>Created</TableHead>
|
||||||
|
<TableHead>Actions</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
@@ -73,14 +81,17 @@ export default async function DashboardPage() {
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<DocumentStatus status={document.status} />
|
<DocumentStatus status={document.status} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-right">
|
<TableCell>
|
||||||
<LocaleDate date={document.created} />
|
<LocaleDate date={document.created} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className="flex cursor-pointer gap-6">
|
||||||
|
<ActionButtons documentId={document.id} />
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
{results.data.length === 0 && (
|
{results.data.length === 0 && (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={4} className="h-24 text-center">
|
<TableCell colSpan={5} className="h-24 text-center">
|
||||||
No results.
|
No results.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { Document } from '@documenso/prisma/client';
|
|||||||
import { DataTable } from '@documenso/ui/primitives/data-table';
|
import { DataTable } from '@documenso/ui/primitives/data-table';
|
||||||
import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination';
|
import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination';
|
||||||
|
|
||||||
|
import { ActionButtons } from '~/components/(dashboard)/table/actions-component';
|
||||||
import { DocumentStatus } from '~/components/formatter/document-status';
|
import { DocumentStatus } from '~/components/formatter/document-status';
|
||||||
import { LocaleDate } from '~/components/formatter/locale-date';
|
import { LocaleDate } from '~/components/formatter/locale-date';
|
||||||
|
|
||||||
@@ -59,6 +60,11 @@ export const DocumentsDataTable = ({ results }: DocumentsDataTableProps) => {
|
|||||||
accessorKey: 'created',
|
accessorKey: 'created',
|
||||||
cell: ({ row }) => <LocaleDate date={row.getValue('created')} />,
|
cell: ({ row }) => <LocaleDate date={row.getValue('created')} />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
header: 'Actions',
|
||||||
|
accessorKey: 'actions',
|
||||||
|
cell: ({ row }) => <ActionButtons documentId={row.original.id} />,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
data={results.data}
|
data={results.data}
|
||||||
perPage={results.perPage}
|
perPage={results.perPage}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { Variants, motion } from 'framer-motion';
|
import { Variants, motion } from 'framer-motion';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
|
import { useTheme } from 'next-themes';
|
||||||
import { useDropzone } from 'react-dropzone';
|
import { useDropzone } from 'react-dropzone';
|
||||||
|
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
@@ -91,6 +92,8 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { theme } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
className={cn('flex', className)}
|
className={cn('flex', className)}
|
||||||
@@ -107,6 +110,7 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
|
|||||||
)}
|
)}
|
||||||
gradient={true}
|
gradient={true}
|
||||||
degrees={120}
|
degrees={120}
|
||||||
|
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
@@ -116,7 +120,6 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
|
|||||||
<motion.div
|
<motion.div
|
||||||
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-right -rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-right -rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
||||||
variants={DocumentDropzoneCardLeftVariants}
|
variants={DocumentDropzoneCardLeftVariants}
|
||||||
transition={{ duration: 0.2 }}
|
|
||||||
>
|
>
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
||||||
@@ -126,7 +129,6 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
|
|||||||
<motion.div
|
<motion.div
|
||||||
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-20 flex aspect-[3/4] w-24 flex-col items-center justify-center gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-20 flex aspect-[3/4] w-24 flex-col items-center justify-center gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
||||||
variants={DocumentDropzoneCardCenterVariants}
|
variants={DocumentDropzoneCardCenterVariants}
|
||||||
transition={{ duration: 0.2 }}
|
|
||||||
>
|
>
|
||||||
<Plus
|
<Plus
|
||||||
strokeWidth="2px"
|
strokeWidth="2px"
|
||||||
@@ -137,7 +139,6 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
|
|||||||
<motion.div
|
<motion.div
|
||||||
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-left rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-left rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
|
||||||
variants={DocumentDropzoneCardRightVariants}
|
variants={DocumentDropzoneCardRightVariants}
|
||||||
transition={{ duration: 0.2 }}
|
|
||||||
>
|
>
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ export type CardMetricProps = {
|
|||||||
|
|
||||||
export const CardMetric = ({ icon: Icon, title, value, className }: CardMetricProps) => {
|
export const CardMetric = ({ icon: Icon, title, value, className }: CardMetricProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={cn('border-border bg-background overflow-hidden rounded-lg border', className)}>
|
<div
|
||||||
|
className={cn(
|
||||||
|
'border-border bg-background overflow-hidden rounded-lg border shadow shadow-transparent duration-200 hover:shadow-slate-100',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="px-4 pb-6 pt-4 sm:px-4 sm:pb-8 sm:pt-4">
|
<div className="px-4 pb-6 pt-4 sm:px-4 sm:pb-8 sm:pt-4">
|
||||||
<div className="flex items-start">
|
<div className="flex items-start">
|
||||||
{Icon && <Icon className="mr-2 h-4 w-4 text-slate-500" />}
|
{Icon && <Icon className="mr-2 h-4 w-4 text-slate-500" />}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Download, Edit, Trash } from 'lucide-react';
|
||||||
|
|
||||||
|
export function ActionButtons({ documentId }: { documentId: number }) {
|
||||||
|
return (
|
||||||
|
<div className="flex cursor-pointer gap-6">
|
||||||
|
<Edit
|
||||||
|
className="text-primary h-5 w-5"
|
||||||
|
onClick={() => {
|
||||||
|
console.log('Edit Document with id: ', documentId);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Download
|
||||||
|
className="text-primary h-5 w-5"
|
||||||
|
onClick={() => {
|
||||||
|
console.log('Download Document with id: ', documentId);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Trash
|
||||||
|
className="text-primary h-5 w-5"
|
||||||
|
onClick={() => {
|
||||||
|
console.log('Delete Document with id: ', documentId);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
6535
package-lock.json
generated
6535
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
|||||||
"packageManager": "npm@8.19.2",
|
"packageManager": "npm@8.19.2",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
"packages/*"
|
"packages/*",
|
||||||
|
"packages/email/.react-email"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
1
packages/email/.gitignore
vendored
Normal file
1
packages/email/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.react-email/
|
||||||
1
packages/email/ambient.d.ts
vendored
Normal file
1
packages/email/ambient.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
declare module '@documenso/tailwind-config';
|
||||||
1
packages/email/index.ts
Normal file
1
packages/email/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { render, renderAsync } from '@react-email/components';
|
||||||
22
packages/email/package.json
Normal file
22
packages/email/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@documenso/email",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "./index.ts",
|
||||||
|
"types": "./index.ts",
|
||||||
|
"license": "MIT",
|
||||||
|
"files": [
|
||||||
|
"templates/"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"dev": "email dev --port 3002 --dir templates"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@documenso/tsconfig": "*",
|
||||||
|
"@documenso/tailwind-config": "*",
|
||||||
|
"@documenso/ui": "*",
|
||||||
|
"@react-email/components": "^0.0.7"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"react-email": "^1.9.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
packages/email/static/clock.png
Normal file
BIN
packages/email/static/clock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
packages/email/static/completed.png
Normal file
BIN
packages/email/static/completed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
packages/email/static/document.png
Normal file
BIN
packages/email/static/document.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
packages/email/static/download.png
Normal file
BIN
packages/email/static/download.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 784 B |
BIN
packages/email/static/logo.png
Normal file
BIN
packages/email/static/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
packages/email/static/review.png
Normal file
BIN
packages/email/static/review.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 708 B |
11
packages/email/tailwind.config.js
Normal file
11
packages/email/tailwind.config.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
|
const baseConfig = require('@documenso/tailwind-config');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...baseConfig,
|
||||||
|
content: [
|
||||||
|
`templates/**/*.{ts,tsx}`,
|
||||||
|
`${path.join(require.resolve('@documenso/ui'), '..')}/**/*.{ts,tsx}`,
|
||||||
|
],
|
||||||
|
};
|
||||||
129
packages/email/templates/document-completed.tsx
Normal file
129
packages/email/templates/document-completed.tsx
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Head,
|
||||||
|
Html,
|
||||||
|
Img,
|
||||||
|
Link,
|
||||||
|
Preview,
|
||||||
|
Section,
|
||||||
|
Tailwind,
|
||||||
|
Text,
|
||||||
|
} from '@react-email/components';
|
||||||
|
|
||||||
|
import * as config from '@documenso/tailwind-config';
|
||||||
|
|
||||||
|
interface DocumentCompletedEmailTemplateProps {
|
||||||
|
downloadLink?: string;
|
||||||
|
reviewLink?: string;
|
||||||
|
documentName?: string;
|
||||||
|
assetBaseUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocumentCompletedEmailTemplate = ({
|
||||||
|
downloadLink = 'https://documenso.com',
|
||||||
|
reviewLink = 'https://documenso.com',
|
||||||
|
documentName = 'Open Source Pledge.pdf',
|
||||||
|
assetBaseUrl = 'http://localhost:3002',
|
||||||
|
}: DocumentCompletedEmailTemplateProps) => {
|
||||||
|
const previewText = `Completed Document`;
|
||||||
|
|
||||||
|
const getAssetUrl = (path: string) => {
|
||||||
|
return new URL(path, assetBaseUrl).toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Html>
|
||||||
|
<Head />
|
||||||
|
<Preview>{previewText}</Preview>
|
||||||
|
<Tailwind
|
||||||
|
config={{
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: config.theme.extend.colors,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Body className="mx-auto my-auto font-sans">
|
||||||
|
<Section className="bg-white">
|
||||||
|
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-2 backdrop-blur-sm">
|
||||||
|
<Section className="p-2">
|
||||||
|
<Img src={getAssetUrl('/static/logo.png')} alt="Documenso Logo" className="h-6" />
|
||||||
|
|
||||||
|
<Section className="mt-4 flex-row items-center justify-center">
|
||||||
|
<div className="flex items-center justify-center p-4">
|
||||||
|
<Img
|
||||||
|
className="h-42"
|
||||||
|
src={getAssetUrl('/static/document.png')}
|
||||||
|
alt="Documenso"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Text className="mb-4 flex items-center justify-center text-center text-base font-semibold text-[#7AC455]">
|
||||||
|
<Img
|
||||||
|
src={getAssetUrl('/static/completed.png')}
|
||||||
|
className="-mb-0.5 mr-2 inline h-7 w-7"
|
||||||
|
/>
|
||||||
|
Completed
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="text-primary mb-0 text-center text-lg font-semibold">
|
||||||
|
“{documentName}” was signed by all signers
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="my-1 text-center text-base text-slate-400">
|
||||||
|
Continue by downloading or reviewing the document.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Section className="mb-6 mt-8 text-center">
|
||||||
|
<Button
|
||||||
|
className="mr-4 inline-flex items-center justify-center rounded-lg border border-solid border-slate-200 px-4 py-2 text-center text-sm font-medium text-black no-underline"
|
||||||
|
href={reviewLink}
|
||||||
|
>
|
||||||
|
<Img
|
||||||
|
src={getAssetUrl('/static/review.png')}
|
||||||
|
className="-mb-1 mr-2 inline h-5 w-5"
|
||||||
|
/>
|
||||||
|
Review
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="inline-flex items-center justify-center rounded-lg border border-solid border-slate-200 px-4 py-2 text-center text-sm font-medium text-black no-underline"
|
||||||
|
href={downloadLink}
|
||||||
|
>
|
||||||
|
<Img
|
||||||
|
src={getAssetUrl('/static/download.png')}
|
||||||
|
className="-mb-1 mr-2 inline h-5 w-5"
|
||||||
|
/>
|
||||||
|
Download
|
||||||
|
</Button>
|
||||||
|
</Section>
|
||||||
|
</Section>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Container className="mx-auto max-w-xl">
|
||||||
|
<Section>
|
||||||
|
<Text className="my-4 text-base text-slate-400">
|
||||||
|
This document was sent using{' '}
|
||||||
|
<Link className="text-[#7AC455]" href="https://documenso.com">
|
||||||
|
Documenso.
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="my-8 text-sm text-slate-400">
|
||||||
|
Documenso
|
||||||
|
<br />
|
||||||
|
2261 Market Street, #5211, San Francisco, CA 94114, USA
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
</Section>
|
||||||
|
</Body>
|
||||||
|
</Tailwind>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DocumentCompletedEmailTemplate;
|
||||||
127
packages/email/templates/document-invite.tsx
Normal file
127
packages/email/templates/document-invite.tsx
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Head,
|
||||||
|
Hr,
|
||||||
|
Html,
|
||||||
|
Img,
|
||||||
|
Link,
|
||||||
|
Preview,
|
||||||
|
Section,
|
||||||
|
Tailwind,
|
||||||
|
Text,
|
||||||
|
} from '@react-email/components';
|
||||||
|
|
||||||
|
import * as config from '@documenso/tailwind-config';
|
||||||
|
|
||||||
|
interface DocumentInviteEmailTemplateProps {
|
||||||
|
inviterName?: string;
|
||||||
|
inviterEmail?: string;
|
||||||
|
documentName?: string;
|
||||||
|
signDocumentLink?: string;
|
||||||
|
assetBaseUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocumentInviteEmailTemplate = ({
|
||||||
|
inviterName = 'Lucas Smith',
|
||||||
|
inviterEmail = 'lucas@documenso.com',
|
||||||
|
documentName = 'Open Source Pledge.pdf',
|
||||||
|
signDocumentLink = 'https://documenso.com',
|
||||||
|
assetBaseUrl = 'http://localhost:3002',
|
||||||
|
}: DocumentInviteEmailTemplateProps) => {
|
||||||
|
const previewText = `Completed Document`;
|
||||||
|
|
||||||
|
const getAssetUrl = (path: string) => {
|
||||||
|
return new URL(path, assetBaseUrl).toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Html>
|
||||||
|
<Head />
|
||||||
|
<Preview>{previewText}</Preview>
|
||||||
|
<Tailwind
|
||||||
|
config={{
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: config.theme.extend.colors,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Body className="mx-auto my-auto bg-white font-sans">
|
||||||
|
<Section>
|
||||||
|
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-2 backdrop-blur-sm">
|
||||||
|
<Section className="p-2">
|
||||||
|
<Img src={getAssetUrl('/static/logo.png')} alt="Documenso Logo" className="h-6" />
|
||||||
|
|
||||||
|
<Section className="mt-4 flex-row items-center justify-center">
|
||||||
|
<div className="flex items-center justify-center p-4">
|
||||||
|
<Img
|
||||||
|
className="h-42"
|
||||||
|
src={getAssetUrl('/static/document.png')}
|
||||||
|
alt="Documenso"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Text className="text-primary mx-auto mb-0 max-w-[80%] text-center text-lg font-semibold">
|
||||||
|
{inviterName} has invited you to sign "{documentName}"
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="my-1 text-center text-base text-slate-400">
|
||||||
|
Continue by signing the document.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Section className="mb-6 mt-8 text-center">
|
||||||
|
<Button
|
||||||
|
className="bg-documenso-500 inline-flex items-center justify-center rounded-lg px-6 py-3 text-center text-sm font-medium text-black no-underline"
|
||||||
|
href={signDocumentLink}
|
||||||
|
>
|
||||||
|
Sign Document
|
||||||
|
</Button>
|
||||||
|
</Section>
|
||||||
|
</Section>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Container className="mx-auto mt-12 max-w-xl">
|
||||||
|
<Section>
|
||||||
|
<Text className="my-4 text-base font-semibold">
|
||||||
|
{inviterName}{' '}
|
||||||
|
<Link className="font-normal text-slate-400" href="mailto:{inviterEmail}">
|
||||||
|
({inviterEmail})
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="mt-2 text-base text-slate-400">
|
||||||
|
{inviterName} has invited you to sign the document "{documentName}".
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Hr className="mx-auto mt-12 max-w-xl" />
|
||||||
|
|
||||||
|
<Container className="mx-auto max-w-xl">
|
||||||
|
<Section>
|
||||||
|
<Text className="my-4 text-base text-slate-400">
|
||||||
|
This document was sent using{' '}
|
||||||
|
<Link className="text-[#7AC455]" href="https://documenso.com">
|
||||||
|
Documenso.
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="my-8 text-sm text-slate-400">
|
||||||
|
Documenso
|
||||||
|
<br />
|
||||||
|
2261 Market Street, #5211, San Francisco, CA 94114, USA
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
</Section>
|
||||||
|
</Body>
|
||||||
|
</Tailwind>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DocumentInviteEmailTemplate;
|
||||||
104
packages/email/templates/document-pending.tsx
Normal file
104
packages/email/templates/document-pending.tsx
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Head,
|
||||||
|
Html,
|
||||||
|
Img,
|
||||||
|
Link,
|
||||||
|
Preview,
|
||||||
|
Section,
|
||||||
|
Tailwind,
|
||||||
|
Text,
|
||||||
|
} from '@react-email/components';
|
||||||
|
|
||||||
|
import * as config from '@documenso/tailwind-config';
|
||||||
|
|
||||||
|
interface DocumentPendingEmailTemplateProps {
|
||||||
|
documentName?: string;
|
||||||
|
assetBaseUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocumentPendingEmailTemplate = ({
|
||||||
|
documentName = 'Open Source Pledge.pdf',
|
||||||
|
assetBaseUrl = 'http://localhost:3002',
|
||||||
|
}: DocumentPendingEmailTemplateProps) => {
|
||||||
|
const previewText = `Pending Document`;
|
||||||
|
|
||||||
|
const getAssetUrl = (path: string) => {
|
||||||
|
return new URL(path, assetBaseUrl).toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Html>
|
||||||
|
<Head />
|
||||||
|
<Preview>{previewText}</Preview>
|
||||||
|
<Tailwind
|
||||||
|
config={{
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: config.theme.extend.colors,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Body className="mx-auto my-auto font-sans">
|
||||||
|
<Section className="bg-white">
|
||||||
|
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-2 backdrop-blur-sm">
|
||||||
|
<Section className="p-2">
|
||||||
|
<Img src={getAssetUrl('/static/logo.png')} alt="Documenso Logo" className="h-6" />
|
||||||
|
|
||||||
|
<Section className="mt-4 flex-row items-center justify-center">
|
||||||
|
<div className="flex items-center justify-center p-4">
|
||||||
|
<Img
|
||||||
|
className="h-42"
|
||||||
|
src={getAssetUrl('/static/document.png')}
|
||||||
|
alt="Documenso"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Text className="mb-4 flex items-center justify-center text-center text-base font-semibold text-blue-500">
|
||||||
|
<Img
|
||||||
|
src={getAssetUrl('/static/clock.png')}
|
||||||
|
className="-mb-0.5 mr-2 inline h-7 w-7"
|
||||||
|
/>
|
||||||
|
Waiting for others
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="text-primary mb-0 text-center text-lg font-semibold">
|
||||||
|
“{documentName}” has been signed
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="mx-auto mb-6 mt-1 max-w-[80%] text-center text-base text-slate-400">
|
||||||
|
We're still waiting for other signers to sign this document.
|
||||||
|
<br />
|
||||||
|
We'll notify you as soon as it's ready.
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Container className="mx-auto max-w-xl">
|
||||||
|
<Section>
|
||||||
|
<Text className="my-4 text-base text-slate-400">
|
||||||
|
This document was sent using{' '}
|
||||||
|
<Link className="text-[#7AC455]" href="https://documenso.com">
|
||||||
|
Documenso.
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="my-8 text-sm text-slate-400">
|
||||||
|
Documenso
|
||||||
|
<br />
|
||||||
|
2261 Market Street, #5211, San Francisco, CA 94114, USA
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
</Section>
|
||||||
|
</Body>
|
||||||
|
</Tailwind>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DocumentPendingEmailTemplate;
|
||||||
5
packages/email/tsconfig.json
Normal file
5
packages/email/tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"extends": "@documenso/tsconfig/react-library.json",
|
||||||
|
"include": ["."],
|
||||||
|
"exclude": ["dist", "build", "node_modules"]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
previewFeatures = ["extendedWhereUnique"]
|
previewFeatures = ["extendedWhereUnique", "jsonProtocol"]
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|||||||
Reference in New Issue
Block a user