mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
app shell
This commit is contained in:
4
apps/web/.babelrc
Normal file
4
apps/web/.babelrc
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"presets": ["next/babel"],
|
||||||
|
"plugins": []
|
||||||
|
}
|
||||||
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": "next/core-web-vitals"
|
"extends": ["next/babel", "next/core-web-vitals"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,224 @@
|
|||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode, Fragment } from "react";
|
||||||
|
import { Disclosure, Menu, Transition } from "@headlessui/react";
|
||||||
|
import { Bars3Icon, BellIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: any;
|
children?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
name: "Tom Cook",
|
||||||
|
email: "tom@example.com",
|
||||||
|
imageUrl:
|
||||||
|
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
|
||||||
|
};
|
||||||
|
const navigation = [
|
||||||
|
{ name: "Dashboard", href: "#", current: true },
|
||||||
|
{ name: "Team", href: "#", current: false },
|
||||||
|
{ name: "Projects", href: "#", current: false },
|
||||||
|
{ name: "Calendar", href: "#", current: false },
|
||||||
|
{ name: "Reports", href: "#", current: false },
|
||||||
|
];
|
||||||
|
const userNavigation = [
|
||||||
|
{ name: "Your Profile", href: "#" },
|
||||||
|
{ name: "Settings", href: "#" },
|
||||||
|
{ name: "Sign out", href: "#" },
|
||||||
|
];
|
||||||
|
|
||||||
|
function classNames(...classes: any) {
|
||||||
|
return classes.filter(Boolean).join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
export default function Layout({ children }: Props) {
|
export default function Layout({ children }: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>Header</div>
|
<div className="min-h-full">
|
||||||
<main>{children}</main>
|
<div className="bg-gray-800 pb-32">
|
||||||
<div>Footer</div>
|
<Disclosure as="nav" className="bg-gray-800">
|
||||||
|
{({ open }: any) => (
|
||||||
|
<>
|
||||||
|
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
|
||||||
|
<div className="border-b border-gray-700">
|
||||||
|
<div className="flex h-16 items-center justify-between px-4 sm:px-0">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<img
|
||||||
|
className="h-8 w-8"
|
||||||
|
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
|
||||||
|
alt="Your Company"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="hidden md:bhellock">
|
||||||
|
<div className="ml-10 flex items-baseline space-x-4">
|
||||||
|
{navigation.map((item) => (
|
||||||
|
<a
|
||||||
|
key={item.name}
|
||||||
|
href={item.href}
|
||||||
|
className={classNames(
|
||||||
|
item.current
|
||||||
|
? "bg-gray-900 text-white"
|
||||||
|
: "text-gray-300 hover:bg-gray-700 hover:text-white",
|
||||||
|
"px-3 py-2 rounded-md text-sm font-medium"
|
||||||
|
)}
|
||||||
|
aria-current={item.current ? "page" : undefined}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="hidden md:block">
|
||||||
|
<div className="ml-4 flex items-center md:ml-6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
|
||||||
|
>
|
||||||
|
<span className="sr-only">View notifications</span>
|
||||||
|
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Profile dropdown */}
|
||||||
|
<Menu as="div" className="relative ml-3">
|
||||||
|
<div>
|
||||||
|
<Menu.Button className="flex max-w-xs items-center rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
|
||||||
|
<span className="sr-only">Open user menu</span>
|
||||||
|
<img
|
||||||
|
className="h-8 w-8 rounded-full"
|
||||||
|
src={user.imageUrl}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</Menu.Button>
|
||||||
|
</div>
|
||||||
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition ease-out duration-100"
|
||||||
|
enterFrom="transform opacity-0 scale-95"
|
||||||
|
enterTo="transform opacity-100 scale-100"
|
||||||
|
leave="transition ease-in duration-75"
|
||||||
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
|
leaveTo="transform opacity-0 scale-95"
|
||||||
|
>
|
||||||
|
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||||
|
{userNavigation.map((item) => (
|
||||||
|
<Menu.Item key={item.name}>
|
||||||
|
{({ active }: any) => (
|
||||||
|
<a
|
||||||
|
href={item.href}
|
||||||
|
className={classNames(
|
||||||
|
active ? "bg-gray-100" : "",
|
||||||
|
"block px-4 py-2 text-sm text-gray-700"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</Menu.Item>
|
||||||
|
))}
|
||||||
|
</Menu.Items>
|
||||||
|
</Transition>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="-mr-2 flex md:hidden">
|
||||||
|
{/* Mobile menu button */}
|
||||||
|
<Disclosure.Button className="inline-flex items-center justify-center rounded-md bg-gray-800 p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
|
||||||
|
<span className="sr-only">Open main menu</span>
|
||||||
|
{open ? (
|
||||||
|
<XMarkIcon
|
||||||
|
className="block h-6 w-6"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Bars3Icon
|
||||||
|
className="block h-6 w-6"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Disclosure.Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Disclosure.Panel className="border-b border-gray-700 md:hidden">
|
||||||
|
<div className="space-y-1 px-2 py-3 sm:px-3">
|
||||||
|
{navigation.map((item) => (
|
||||||
|
<Disclosure.Button
|
||||||
|
key={item.name}
|
||||||
|
as="a"
|
||||||
|
href={item.href}
|
||||||
|
className={classNames(
|
||||||
|
item.current
|
||||||
|
? "bg-gray-900 text-white"
|
||||||
|
: "text-gray-300 hover:bg-gray-700 hover:text-white",
|
||||||
|
"block px-3 py-2 rounded-md text-base font-medium"
|
||||||
|
)}
|
||||||
|
aria-current={item.current ? "page" : undefined}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</Disclosure.Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="border-t border-gray-700 pt-4 pb-3">
|
||||||
|
<div className="flex items-center px-5">
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<img
|
||||||
|
className="h-10 w-10 rounded-full"
|
||||||
|
src={user.imageUrl}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="ml-3">
|
||||||
|
<div className="text-base font-medium leading-none text-white">
|
||||||
|
{user.name}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm font-medium leading-none text-gray-400">
|
||||||
|
{user.email}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ml-auto flex-shrink-0 rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
|
||||||
|
>
|
||||||
|
<span className="sr-only">View notifications</span>
|
||||||
|
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="mt-3 space-y-1 px-2">
|
||||||
|
{userNavigation.map((item) => (
|
||||||
|
<Disclosure.Button
|
||||||
|
key={item.name}
|
||||||
|
as="a"
|
||||||
|
href={item.href}
|
||||||
|
className="block rounded-md px-3 py-2 text-base font-medium text-gray-400 hover:bg-gray-700 hover:text-white"
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</Disclosure.Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Disclosure.Panel>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Disclosure>
|
||||||
|
<header className="py-10">
|
||||||
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight text-white">
|
||||||
|
Dashboard
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main className="-mt-32">
|
||||||
|
<div className="mx-auto max-w-7xl px-4 pb-12 sm:px-6 lg:px-8">
|
||||||
|
<div className="rounded-lg bg-white px-5 py-6 shadow sm:px-6">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
5228
apps/web/package-lock.json
generated
5228
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,18 +9,25 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@headlessui/react": "^1.7.4",
|
||||||
|
"@heroicons/react": "^2.0.13",
|
||||||
"@prisma/client": "^4.6.1",
|
"@prisma/client": "^4.6.1",
|
||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "18.0.25",
|
||||||
"@types/react-dom": "18.0.9",
|
"@types/react-dom": "18.0.9",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"eslint-config-next": "13.0.3",
|
"eslint-config-next": "13.0.3",
|
||||||
|
"install": "^0.13.0",
|
||||||
"next": "13.0.3",
|
"next": "13.0.3",
|
||||||
|
"npm": "^9.1.3",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prisma": "^4.6.1"
|
"autoprefixer": "^10.4.13",
|
||||||
|
"postcss": "^8.4.19",
|
||||||
|
"prisma": "^4.6.1",
|
||||||
|
"tailwindcss": "^3.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import "../styles/tailwind.css";
|
||||||
import { ReactElement, ReactNode } from "react";
|
import { ReactElement, ReactNode } from "react";
|
||||||
import type { AppProps } from "next/app";
|
import type { AppProps } from "next/app";
|
||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
|
|||||||
21
apps/web/pages/_document.jsx
Normal file
21
apps/web/pages/_document.jsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Head, Html, Main, NextScript } from "next/document";
|
||||||
|
import Script from "next/script";
|
||||||
|
|
||||||
|
export default function Document(props) {
|
||||||
|
let pageProps = props.__NEXT_DATA__?.props?.pageProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Html
|
||||||
|
className="h-full scroll-smooth bg-white font-normal antialiased"
|
||||||
|
lang="en"
|
||||||
|
>
|
||||||
|
<Head>
|
||||||
|
<meta name="color-scheme"></meta>
|
||||||
|
</Head>
|
||||||
|
<body className="flex h-full flex-col">
|
||||||
|
<Main />
|
||||||
|
<NextScript />
|
||||||
|
</body>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ import Layout from "../components/layout";
|
|||||||
import type { NextPageWithLayout } from "./_app";
|
import type { NextPageWithLayout } from "./_app";
|
||||||
|
|
||||||
const Page: NextPageWithLayout = () => {
|
const Page: NextPageWithLayout = () => {
|
||||||
return <p>hello world</p>;
|
return <p className="text-red-900">This is the index page</p>;
|
||||||
};
|
};
|
||||||
|
|
||||||
Page.getLayout = function getLayout(page: ReactElement) {
|
Page.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
|||||||
6
apps/web/postcss.config.js
Normal file
6
apps/web/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -1,129 +0,0 @@
|
|||||||
.container {
|
|
||||||
padding: 0 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 4rem 0;
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
padding: 2rem 0;
|
|
||||||
border-top: 1px solid #eaeaea;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer a {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title a {
|
|
||||||
color: #0070f3;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title a:hover,
|
|
||||||
.title a:focus,
|
|
||||||
.title a:active {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.15;
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title,
|
|
||||||
.description {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin: 4rem 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code {
|
|
||||||
background: #fafafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 0.75rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
|
||||||
Bitstream Vera Sans Mono, Courier New, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
margin: 1rem;
|
|
||||||
padding: 1.5rem;
|
|
||||||
text-align: left;
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
border-radius: 10px;
|
|
||||||
transition: color 0.15s ease, border-color 0.15s ease;
|
|
||||||
max-width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover,
|
|
||||||
.card:focus,
|
|
||||||
.card:active {
|
|
||||||
color: #0070f3;
|
|
||||||
border-color: #0070f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card h2 {
|
|
||||||
margin: 0 0 1rem 0;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: 1em;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.grid {
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.card,
|
|
||||||
.footer {
|
|
||||||
border-color: #222;
|
|
||||||
}
|
|
||||||
.code {
|
|
||||||
background: #111;
|
|
||||||
}
|
|
||||||
.logo img {
|
|
||||||
filter: invert(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
html,
|
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
|
||||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
html {
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
color: white;
|
|
||||||
background: black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
apps/web/styles/tailwind.css
Normal file
15
apps/web/styles/tailwind.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap");
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
#__next {
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
} */
|
||||||
27
apps/web/tailwind.config.js
Normal file
27
apps/web/tailwind.config.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// const defaultTheme = require("tailwindcss/defaultTheme");
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||||
|
"./components/**/*.{js,ts,jsx,tsx}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
// sans: ['Monteserrat', 'sans-serif'],
|
||||||
|
monteserrat: ["Monteserrat", "sans-serif"],
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
neon: "#37f095",
|
||||||
|
brown: "#353434",
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
"4xl": "2rem",
|
||||||
|
},
|
||||||
|
maxWidth: {
|
||||||
|
"2xl": "40rem",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user