initial commit

This commit is contained in:
Derock 2023-09-08 22:45:58 -04:00
commit 1d4bdf0446
No known key found for this signature in database
65 changed files with 6622 additions and 0 deletions

36
.gitignore vendored Normal file
View file

@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
.pnp
.pnp.js
# testing
coverage
# next.js
.next/
out/
build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# turbo
.turbo
# vercel
.vercel

1
.npmrc Normal file
View file

@ -0,0 +1 @@
auto-install-peers = true

81
README.md Normal file
View file

@ -0,0 +1,81 @@
# Turborepo starter
This is an official starter Turborepo.
## Using this example
Run the following command:
```sh
npx create-turbo@latest
```
## What's inside?
This Turborepo includes the following packages/apps:
### Apps and Packages
- `docs`: a [Next.js](https://nextjs.org/) app
- `web`: another [Next.js](https://nextjs.org/) app
- `ui`: a stub React component library shared by both `web` and `docs` applications
- `eslint-config-custom`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`)
- `tsconfig`: `tsconfig.json`s used throughout the monorepo
Each package/app is 100% [TypeScript](https://www.typescriptlang.org/).
### Utilities
This Turborepo has some additional tools already setup for you:
- [TypeScript](https://www.typescriptlang.org/) for static type checking
- [ESLint](https://eslint.org/) for code linting
- [Prettier](https://prettier.io) for code formatting
### Build
To build all apps and packages, run the following command:
```
cd my-turborepo
pnpm build
```
### Develop
To develop all apps and packages, run the following command:
```
cd my-turborepo
pnpm dev
```
### Remote Caching
Turborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.
By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup), then enter the following commands:
```
cd my-turborepo
npx turbo login
```
This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).
Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo:
```
npx turbo link
```
## Useful Links
Learn more about the power of Turborepo:
- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks)
- [Caching](https://turbo.build/repo/docs/core-concepts/caching)
- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching)
- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering)
- [Configuration Options](https://turbo.build/repo/docs/reference/configuration)
- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference)

3
apps/api/.eslintrc.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
extends: ["custom/library"],
};

8
apps/api/README.md Normal file
View file

@ -0,0 +1,8 @@
```
bun install
bun run dev
```
```
open http://localhost:3000
```

14
apps/api/package.json Normal file
View file

@ -0,0 +1,14 @@
{
"name": "api",
"scripts": {
"dev": "bun run --hot src/index.ts"
},
"dependencies": {
"@hono/zod-validator": "^0.1.8",
"hono": "^3.5.4",
"zod": "^3.22.2"
},
"devDependencies": {
"bun-types": "^0.6.2"
}
}

15
apps/api/src/index.ts Normal file
View file

@ -0,0 +1,15 @@
import { Hono } from "hono";
import { HonoRouter } from "./router";
import { logger } from "hono/logger";
const app = new Hono();
// logger
app.use("*", logger());
const router = new HonoRouter(app)
.register(import("./routes/root"))
.register(import("./routes/users"));
export type AppType = typeof router.hono;
export default router.hono;

38
apps/api/src/router.ts Normal file
View file

@ -0,0 +1,38 @@
import { Env, Hono, Schema } from "hono";
type Imported<T> = T | Promise<{ default: T }>;
/**
* A very simple route manager for Hono to keep the types correct for RPC.
*/
export class HonoRouter<
E extends Env = {},
S extends Schema = {},
B extends string = "/",
> {
public readonly hono: Hono<E, S, B>;
constructor(hono: Hono<E, S, B>) {
this.hono = hono;
}
/**
* Register route(s).
*
* @example router.register(import("./routes/root"));
*
* @param cb The function that is ran to register the route.
* @returns This.
*/
public register<En extends Env, Sn extends Schema>(
cb: Imported<(hono: Hono) => Hono<En, Sn, B>>
) {
if (cb instanceof Promise) {
cb.then((cb) => cb.default(this.hono as unknown as Hono));
} else {
cb(this.hono as unknown as Hono);
}
return this as unknown as HonoRouter<E, S & Sn, B>;
}
}

View file

@ -0,0 +1,4 @@
import { Hono } from "hono";
export default (router: Hono) =>
router.get("/", (c) => c.jsonT({ status: "ok" }));

View file

@ -0,0 +1,23 @@
import { Hono } from "hono";
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
export default (router: Hono) =>
router
.get("/users", (c) => c.text("Hello Hono!"))
.post(
// path
"/users/create",
// body validator
zValidator(
"json",
z.object({
username: z.string(),
password: z.string(),
})
),
// handler
(c) => c.jsonT({ status: "ok" })
);

8
apps/api/src/test.ts Normal file
View file

@ -0,0 +1,8 @@
import { hc } from "hono/client";
import type { AppType } from ".";
const api = hc<AppType>("http://localhost:3000");
api.users.create.$post({
json: { username: "string", password: "asdf" },
});

11
apps/api/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"extends": "tsconfig/base.json",
"compilerOptions": {
"esModuleInterop": true,
"strict": true,
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"lib": ["ESNext", "DOM"]
},
"include": ["src/**/*"]
}

3
apps/docs/.eslintrc.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
extends: ["custom/next"],
};

34
apps/docs/.gitignore vendored Normal file
View file

@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel

28
apps/docs/README.md Normal file
View file

@ -0,0 +1,28 @@
## Getting Started
First, run the development server:
```bash
yarn dev
```
Open [http://localhost:3001](http://localhost:3001) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, like `api/hello/route.ts` would map to [http://localhost:3001/api/hello](http://localhost:3001/api/hello).
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

BIN
apps/docs/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

50
apps/docs/app/globals.css Normal file
View file

@ -0,0 +1,50 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",
"Fira Mono", "Droid Sans Mono", "Courier New", monospace;
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
--card-rgb: 100, 100, 100;
--card-border-rgb: 200, 200, 200;
--glow-conic: conic-gradient(
from 180deg at 50% 50%,
#2a8af6 0deg,
#a853ba 180deg,
#e92a67 360deg
);
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a {
color: inherit;
text-decoration: none;
}

22
apps/docs/app/layout.tsx Normal file
View file

@ -0,0 +1,22 @@
import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Turborepo",
description: "Generated by create turbo",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}

View file

@ -0,0 +1,303 @@
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 6rem;
min-height: 100vh;
}
.vercelLogo {
filter: invert(1);
}
.description {
display: inherit;
justify-content: inherit;
align-items: inherit;
font-size: 0.85rem;
max-width: var(--max-width);
width: 100%;
z-index: 2;
font-family: var(--font-mono);
}
.description a {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
}
.description p {
position: relative;
margin: 0;
padding: 1rem;
background-color: rgba(var(--callout-rgb), 0.5);
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
border-radius: var(--border-radius);
}
.code {
font-weight: 700;
font-family: var(--font-mono);
}
.hero {
display: flex;
position: relative;
place-items: center;
}
.heroContent {
display: flex;
position: relative;
z-index: 0;
padding-bottom: 4rem;
flex-direction: column;
gap: 2rem;
justify-content: space-between;
align-items: center;
width: auto;
font-family: system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial,
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
padding-top: 48px;
@media (min-width: 768px) {
padding-top: 4rem;
padding-bottom: 6rem;
}
@media (min-width: 1024px) {
padding-top: 5rem;
padding-bottom: 8rem;
}
}
.logos {
display: flex;
z-index: 50;
justify-content: center;
align-items: center;
width: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(25%, auto));
max-width: 100%;
width: var(--max-width);
}
.card {
padding: 1rem 1.2rem;
border-radius: var(--border-radius);
background: rgba(var(--card-rgb), 0);
border: 1px solid rgba(var(--card-border-rgb), 0);
transition: background 200ms, border 200ms;
}
.card span {
display: inline-block;
transition: transform 200ms;
}
.card h2 {
font-weight: 600;
margin-bottom: 0.7rem;
}
.card p {
margin: 0;
opacity: 0.6;
font-size: 0.9rem;
line-height: 1.5;
max-width: 30ch;
}
@media (prefers-reduced-motion) {
.card:hover span {
transform: none;
}
}
/* Mobile */
@media (max-width: 700px) {
.content {
padding: 4rem;
}
.grid {
grid-template-columns: 1fr;
margin-bottom: 120px;
max-width: 320px;
text-align: center;
}
.card {
padding: 1rem 2.5rem;
}
.card h2 {
margin-bottom: 0.5rem;
}
.center {
padding: 8rem 0 6rem;
}
.center::before {
transform: none;
height: 300px;
}
.description {
font-size: 0.8rem;
}
.description a {
padding: 1rem;
}
.description p,
.description div {
display: flex;
justify-content: center;
position: fixed;
width: 100%;
}
.description p {
align-items: center;
inset: 0 0 auto;
padding: 2rem 1rem 1.4rem;
border-radius: 0;
border: none;
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
background: linear-gradient(
to bottom,
rgba(var(--background-start-rgb), 1),
rgba(var(--callout-rgb), 0.5)
);
background-clip: padding-box;
backdrop-filter: blur(24px);
}
.description div {
align-items: flex-end;
pointer-events: none;
inset: auto 0 0;
padding: 2rem;
height: 200px;
background: linear-gradient(
to bottom,
transparent 0%,
rgb(var(--background-end-rgb)) 40%
);
z-index: 1;
}
}
/* Enable hover only on non-touch devices */
@media (hover: hover) and (pointer: fine) {
.card:hover {
background: rgba(var(--card-rgb), 0.1);
border: 1px solid rgba(var(--card-border-rgb), 0.15);
}
.card:hover span {
transform: translateX(4px);
}
}
.circles {
position: absolute;
min-width: 614px;
min-height: 614px;
}
.logo {
z-index: 50;
width: 120px;
height: 120px;
}
.logoGradientContainer {
display: flex;
position: absolute;
z-index: 50;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
}
.turborepoWordmarkContainer {
display: flex;
z-index: 50;
padding-left: 1.5rem;
padding-right: 1.5rem;
flex-direction: column;
gap: 1.25rem;
justify-content: center;
align-items: center;
text-align: center;
@media (min-width: 1024px) {
gap: 1.5rem;
}
}
.turborepoWordmark {
width: 160px;
fill: white;
@media (min-width: 768px) {
width: 200px;
}
}
.code {
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace;
font-weight: 700;
}
/* Tablet and Smaller Desktop */
@media (min-width: 701px) and (max-width: 1120px) {
.grid {
grid-template-columns: repeat(2, 50%);
}
}
/* Gradients */
.gradient {
position: absolute;
mix-blend-mode: normal;
will-change: filter;
}
.gradientSmall {
filter: blur(32px);
}
.gradientLarge {
filter: blur(75px);
}
.glowConic {
background-image: var(--glow-conic);
}
.logoGradient {
opacity: 0.9;
width: 120px;
height: 120px;
}
.backgroundGradient {
top: -500px;
width: 1000px;
height: 1000px;
opacity: 0.15;
}

136
apps/docs/app/page.tsx Normal file
View file

@ -0,0 +1,136 @@
import Image from "next/image";
import { Card } from "ui";
import styles from "./page.module.css";
function Gradient({
conic,
className,
small,
}: {
small?: boolean;
conic?: boolean;
className?: string;
}): JSX.Element {
return (
<span
className={[
styles.gradient,
conic ? styles.glowConic : undefined,
small ? styles.gradientSmall : styles.gradientLarge,
className,
]
.filter(Boolean)
.join(" ")}
/>
);
}
const LINKS = [
{
title: "Docs",
href: "https://turbo.build/repo/docs",
description: "Find in-depth information about Turborepo features and API.",
},
{
title: "Learn",
href: "https://turbo.build/repo/docs/handbook",
description: "Learn more about monorepos with our handbook.",
},
{
title: "Templates",
href: "https://turbo.build/repo/docs/getting-started/from-example",
description: "Choose from over 15 examples and deploy with a single click.",
},
{
title: "Deploy",
href: "https://vercel.com/new",
description:
" Instantly deploy your Turborepo to a shareable URL with Vercel.",
},
];
export default function Page(): JSX.Element {
return (
<main className={styles.main}>
<div className={styles.description}>
<p>
examples/basic&nbsp;
<code className={styles.code}>docs</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-turbo&utm_medium=basic&utm_campaign=create-turbo"
rel="noopener noreferrer"
target="_blank"
>
By{" "}
<Image
alt="Vercel Logo"
className={styles.vercelLogo}
height={24}
priority
src="/vercel.svg"
width={100}
/>
</a>
</div>
</div>
<div className={styles.hero}>
<div className={styles.heroContent}>
<div className={styles.logos}>
<div className={styles.circles}>
<Image
alt="Turborepo"
height={614}
src="circles.svg"
width={614}
/>
</div>
<div className={styles.logoGradientContainer}>
<Gradient className={styles.logoGradient} conic small />
</div>
<div className={styles.logo}>
<Image
alt=""
height={120}
priority
src="turborepo.svg"
width={120}
/>
</div>
</div>
<Gradient className={styles.backgroundGradient} conic />
<div className={styles.turborepoWordmarkContainer}>
<svg
className={styles.turborepoWordmark}
viewBox="0 0 506 50"
width={200}
xmlns="http://www.w3.org/2000/svg"
>
<title>Turborepo logo</title>
<path d="M53.7187 12.0038V1.05332H0.945312V12.0038H20.8673V48.4175H33.7968V12.0038H53.7187Z" />
<path d="M83.5362 49.1431C99.764 49.1431 108.67 40.8972 108.67 27.3081V1.05332H95.7401V26.0547C95.7401 33.6409 91.7821 37.9287 83.5362 37.9287C75.2904 37.9287 71.3324 33.6409 71.3324 26.0547V1.05332H58.4029V27.3081C58.4029 40.8972 67.3084 49.1431 83.5362 49.1431Z" />
<path d="M128.462 32.7174H141.325L151.484 48.4175H166.327L154.848 31.3321C161.313 29.0232 165.271 23.8778 165.271 16.8853C165.271 6.72646 157.685 1.05332 146.141 1.05332H115.532V48.4175H128.462V32.7174ZM128.462 22.4925V11.8719H145.481C150.033 11.8719 152.54 13.8509 152.54 17.2152C152.54 20.3816 150.033 22.4925 145.481 22.4925H128.462Z" />
<path d="M171.287 48.4175H205.128C215.683 48.4175 221.752 43.404 221.752 35.0262C221.752 29.419 218.189 25.593 213.967 23.8778C216.87 22.4925 220.432 19.1942 220.432 13.9828C220.432 5.60502 214.495 1.05332 204.006 1.05332H171.287V48.4175ZM183.689 19.59V11.542H202.687C206.249 11.542 208.228 12.9273 208.228 15.566C208.228 18.2047 206.249 19.59 202.687 19.59H183.689ZM183.689 29.2871H203.875C207.371 29.2871 209.284 31.0022 209.284 33.5749C209.284 36.1476 207.371 37.8628 203.875 37.8628H183.689V29.2871Z" />
<path d="M253.364 0.261719C236.806 0.261719 224.866 10.6185 224.866 24.7354C224.866 38.8523 236.806 49.2091 253.364 49.2091C269.922 49.2091 281.796 38.8523 281.796 24.7354C281.796 10.6185 269.922 0.261719 253.364 0.261719ZM253.364 11.4761C262.072 11.4761 268.602 16.6215 268.602 24.7354C268.602 32.8493 262.072 37.9947 253.364 37.9947C244.656 37.9947 238.126 32.8493 238.126 24.7354C238.126 16.6215 244.656 11.4761 253.364 11.4761Z" />
<path d="M300.429 32.7174H313.292L323.451 48.4175H338.294L326.815 31.3321C333.28 29.0232 337.238 23.8778 337.238 16.8853C337.238 6.72646 329.652 1.05332 318.108 1.05332H287.499V48.4175H300.429V32.7174ZM300.429 22.4925V11.8719H317.448C322 11.8719 324.507 13.8509 324.507 17.2152C324.507 20.3816 322 22.4925 317.448 22.4925H300.429Z" />
<path d="M343.254 1.05332V48.4175H389.299V37.467H355.92V29.7489H385.539V19.0622H355.92V12.0038H389.299V1.05332H343.254Z" />
<path d="M408.46 33.3111H425.677C437.221 33.3111 444.807 27.7699 444.807 17.2152C444.807 6.59453 437.221 1.05332 425.677 1.05332H395.53V48.4175H408.46V33.3111ZM408.46 22.5585V11.8719H424.951C429.569 11.8719 432.076 13.8509 432.076 17.2152C432.076 20.5135 429.569 22.5585 424.951 22.5585H408.46Z" />
<path d="M476.899 0.261719C460.341 0.261719 448.401 10.6185 448.401 24.7354C448.401 38.8523 460.341 49.2091 476.899 49.2091C493.456 49.2091 505.33 38.8523 505.33 24.7354C505.33 10.6185 493.456 0.261719 476.899 0.261719ZM476.899 11.4761C485.606 11.4761 492.137 16.6215 492.137 24.7354C492.137 32.8493 485.606 37.9947 476.899 37.9947C468.191 37.9947 461.66 32.8493 461.66 24.7354C461.66 16.6215 468.191 11.4761 476.899 11.4761Z" />
</svg>
</div>
</div>
</div>
<div className={styles.grid}>
{LINKS.map(({ title, href, description }) => (
<Card className={styles.card} href={href} key={title} title={title}>
{description}
</Card>
))}
</div>
</main>
);
}

5
apps/docs/next-env.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

4
apps/docs/next.config.js Normal file
View file

@ -0,0 +1,4 @@
module.exports = {
reactStrictMode: true,
transpilePackages: ["ui"],
};

26
apps/docs/package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "docs",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev --port 3001",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ui": "workspace:*"
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.4.19",
"@types/node": "^17.0.12",
"@types/react": "^18.0.22",
"@types/react-dom": "^18.0.7",
"eslint-config-custom": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "^4.5.3"
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="614" height="614">
<defs xmlns="http://www.w3.org/2000/svg">
<radialGradient id="radial" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fff"></stop>
<stop offset="60%" stop-color="#fff" stop-opacity="0"></stop>
</radialGradient>
</defs>
<circle cx="50" cy="50" r="25" stroke-width=".2" style="fill:none; stroke:rgba(255,255,255,.1);">
<animate attributeName="opacity" values="1;0.1;0.1;1" dur="3s" begin="0.2s" repeatCount="indefinite"></animate>
</circle>
<circle cx="50" cy="50" r="25" stroke-width=".2" style="fill:url(#radial); fill-opacity:.1;">
<animate attributeName="opacity" values="1;0.5;0.5;1" dur="3s" repeatCount="indefinite"></animate>
</circle><circle cx="50" cy="50" r="45" stroke-width=".2" style="fill:none; stroke:rgba(255,255,255,.1);">
<animate attributeName="opacity" values="1;0.1;0.1;1" dur="3s" begin="0.4s" repeatCount="indefinite"></animate>
</circle>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,32 @@
<svg width="104" height="104" viewBox="0 0 104 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_17)">
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="black" fill-opacity="0.64"/>
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="url(#paint0_linear_1_17)" fill-opacity="0.15"/>
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="black" fill-opacity="0.5"/>
<path d="M0.538475 52C0.538475 33.6146 10.347 16.6257 26.2692 7.43301C42.1915 -1.7597 61.8085 -1.7597 77.7308 7.43301C93.653 16.6257 103.462 33.6146 103.462 52C103.462 70.3854 93.653 87.3743 77.7308 96.567C61.8085 105.76 42.1915 105.76 26.2692 96.567C10.347 87.3743 0.538475 70.3854 0.538475 52Z" stroke="url(#paint1_radial_1_17)" stroke-opacity="0.15"/>
<path d="M0.538475 52C0.538475 33.6146 10.347 16.6257 26.2692 7.43301C42.1915 -1.7597 61.8085 -1.7597 77.7308 7.43301C93.653 16.6257 103.462 33.6146 103.462 52C103.462 70.3854 93.653 87.3743 77.7308 96.567C61.8085 105.76 42.1915 105.76 26.2692 96.567C10.347 87.3743 0.538475 70.3854 0.538475 52Z" stroke="url(#paint2_linear_1_17)" stroke-opacity="0.5"/>
<path d="M51.8878 37.9262C44.1892 37.9262 37.9258 44.1896 37.9258 51.8882C37.9258 59.5868 44.1892 65.8502 51.8878 65.8502C59.5864 65.8502 65.8498 59.5868 65.8498 51.8882C65.8498 44.1896 59.5864 37.9262 51.8878 37.9262ZM51.8878 59.1136C47.8968 59.1136 44.6624 55.8792 44.6624 51.8882C44.6624 47.8972 47.8968 44.6628 51.8878 44.6628C55.8788 44.6628 59.1132 47.8972 59.1132 51.8882C59.1132 55.8792 55.8788 59.1136 51.8878 59.1136Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0581 35.633V30.42C64.3889 31.0258 73.3901 40.4066 73.3901 51.8882C73.3901 63.3698 64.3889 72.748 53.0581 73.3564V68.1434C61.5029 67.5402 68.1901 60.4838 68.1901 51.8882C68.1901 43.2926 61.5029 36.2362 53.0581 35.633ZM39.5745 62.5482C37.3359 59.9638 35.8929 56.6722 35.6355 53.0582H30.4199C30.6903 58.1152 32.7131 62.7042 35.8825 66.2376L39.5719 62.5482H39.5745ZM50.7182 73.3564V68.1434C47.1016 67.886 43.81 66.4456 41.2256 64.2044L37.5362 67.8938C41.0722 71.0658 45.6612 73.086 50.7156 73.3564H50.7182Z" fill="url(#paint3_linear_1_17)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1_17" x1="52" y1="-8" x2="52" y2="112" gradientUnits="userSpaceOnUse">
<stop stop-color="#3286F1"/>
<stop offset="1" stop-color="#C43AC4"/>
</linearGradient>
<radialGradient id="paint1_radial_1_17" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(52 -7.99999) rotate(90) scale(154.286 154.286)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white"/>
</radialGradient>
<linearGradient id="paint2_linear_1_17" x1="-8" y1="-8" x2="18.25" y2="40.75" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_1_17" x1="53.9007" y1="33.4389" x2="32.7679" y2="54.5717" gradientUnits="userSpaceOnUse">
<stop stop-color="#0096FF"/>
<stop offset="1" stop-color="#FF1E56"/>
</linearGradient>
<clipPath id="clip0_1_17">
<rect width="104" height="104" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

8
apps/docs/tsconfig.json Normal file
View file

@ -0,0 +1,8 @@
{
"extends": "tsconfig/nextjs.json",
"compilerOptions": {
"plugins": [{ "name": "next" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

3
apps/web/.eslintrc.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
extends: ["custom/next"],
};

34
apps/web/.gitignore vendored Normal file
View file

@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel

28
apps/web/README.md Normal file
View file

@ -0,0 +1,28 @@
## Getting Started
First, run the development server:
```bash
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, like `api/hello/route.ts` would map to [http://localhost:3000/api/hello](http://localhost:3000/api/hello).
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

BIN
apps/web/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

50
apps/web/app/globals.css Normal file
View file

@ -0,0 +1,50 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",
"Fira Mono", "Droid Sans Mono", "Courier New", monospace;
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
--card-rgb: 100, 100, 100;
--card-border-rgb: 200, 200, 200;
--glow-conic: conic-gradient(
from 180deg at 50% 50%,
#2a8af6 0deg,
#a853ba 180deg,
#e92a67 360deg
);
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a {
color: inherit;
text-decoration: none;
}

22
apps/web/app/layout.tsx Normal file
View file

@ -0,0 +1,22 @@
import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Turborepo",
description: "Generated by create turbo",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}

View file

@ -0,0 +1,303 @@
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 6rem;
min-height: 100vh;
}
.vercelLogo {
filter: invert(1);
}
.description {
display: inherit;
justify-content: inherit;
align-items: inherit;
font-size: 0.85rem;
max-width: var(--max-width);
width: 100%;
z-index: 2;
font-family: var(--font-mono);
}
.description a {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
}
.description p {
position: relative;
margin: 0;
padding: 1rem;
background-color: rgba(var(--callout-rgb), 0.5);
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
border-radius: var(--border-radius);
}
.code {
font-weight: 700;
font-family: var(--font-mono);
}
.hero {
display: flex;
position: relative;
place-items: center;
}
.heroContent {
display: flex;
position: relative;
z-index: 0;
padding-bottom: 4rem;
flex-direction: column;
gap: 2rem;
justify-content: space-between;
align-items: center;
width: auto;
font-family: system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial,
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
padding-top: 48px;
@media (min-width: 768px) {
padding-top: 4rem;
padding-bottom: 6rem;
}
@media (min-width: 1024px) {
padding-top: 5rem;
padding-bottom: 8rem;
}
}
.logos {
display: flex;
z-index: 50;
justify-content: center;
align-items: center;
width: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(25%, auto));
max-width: 100%;
width: var(--max-width);
}
.card {
padding: 1rem 1.2rem;
border-radius: var(--border-radius);
background: rgba(var(--card-rgb), 0);
border: 1px solid rgba(var(--card-border-rgb), 0);
transition: background 200ms, border 200ms;
}
.card span {
display: inline-block;
transition: transform 200ms;
}
.card h2 {
font-weight: 600;
margin-bottom: 0.7rem;
}
.card p {
margin: 0;
opacity: 0.6;
font-size: 0.9rem;
line-height: 1.5;
max-width: 30ch;
}
@media (prefers-reduced-motion) {
.card:hover span {
transform: none;
}
}
/* Mobile */
@media (max-width: 700px) {
.content {
padding: 4rem;
}
.grid {
grid-template-columns: 1fr;
margin-bottom: 120px;
max-width: 320px;
text-align: center;
}
.card {
padding: 1rem 2.5rem;
}
.card h2 {
margin-bottom: 0.5rem;
}
.center {
padding: 8rem 0 6rem;
}
.center::before {
transform: none;
height: 300px;
}
.description {
font-size: 0.8rem;
}
.description a {
padding: 1rem;
}
.description p,
.description div {
display: flex;
justify-content: center;
position: fixed;
width: 100%;
}
.description p {
align-items: center;
inset: 0 0 auto;
padding: 2rem 1rem 1.4rem;
border-radius: 0;
border: none;
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
background: linear-gradient(
to bottom,
rgba(var(--background-start-rgb), 1),
rgba(var(--callout-rgb), 0.5)
);
background-clip: padding-box;
backdrop-filter: blur(24px);
}
.description div {
align-items: flex-end;
pointer-events: none;
inset: auto 0 0;
padding: 2rem;
height: 200px;
background: linear-gradient(
to bottom,
transparent 0%,
rgb(var(--background-end-rgb)) 40%
);
z-index: 1;
}
}
/* Enable hover only on non-touch devices */
@media (hover: hover) and (pointer: fine) {
.card:hover {
background: rgba(var(--card-rgb), 0.1);
border: 1px solid rgba(var(--card-border-rgb), 0.15);
}
.card:hover span {
transform: translateX(4px);
}
}
.circles {
position: absolute;
min-width: 614px;
min-height: 614px;
}
.logo {
z-index: 50;
width: 120px;
height: 120px;
}
.logoGradientContainer {
display: flex;
position: absolute;
z-index: 50;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
}
.turborepoWordmarkContainer {
display: flex;
z-index: 50;
padding-left: 1.5rem;
padding-right: 1.5rem;
flex-direction: column;
gap: 1.25rem;
justify-content: center;
align-items: center;
text-align: center;
@media (min-width: 1024px) {
gap: 1.5rem;
}
}
.turborepoWordmark {
width: 160px;
fill: white;
@media (min-width: 768px) {
width: 200px;
}
}
.code {
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace;
font-weight: 700;
}
/* Tablet and Smaller Desktop */
@media (min-width: 701px) and (max-width: 1120px) {
.grid {
grid-template-columns: repeat(2, 50%);
}
}
/* Gradients */
.gradient {
position: absolute;
mix-blend-mode: normal;
will-change: filter;
}
.gradientSmall {
filter: blur(32px);
}
.gradientLarge {
filter: blur(75px);
}
.glowConic {
background-image: var(--glow-conic);
}
.logoGradient {
opacity: 0.9;
width: 120px;
height: 120px;
}
.backgroundGradient {
top: -500px;
width: 1000px;
height: 1000px;
opacity: 0.15;
}

136
apps/web/app/page.tsx Normal file
View file

@ -0,0 +1,136 @@
import Image from "next/image";
import { Card } from "ui";
import styles from "./page.module.css";
function Gradient({
conic,
className,
small,
}: {
small?: boolean;
conic?: boolean;
className?: string;
}): JSX.Element {
return (
<span
className={[
styles.gradient,
conic ? styles.glowConic : undefined,
small ? styles.gradientSmall : styles.gradientLarge,
className,
]
.filter(Boolean)
.join(" ")}
/>
);
}
const LINKS = [
{
title: "Docs",
href: "https://turbo.build/repo/docs",
description: "Find in-depth information about Turborepo features and API.",
},
{
title: "Learn",
href: "https://turbo.build/repo/docs/handbook",
description: "Learn more about monorepos with our handbook.",
},
{
title: "Templates",
href: "https://turbo.build/repo/docs/getting-started/from-example",
description: "Choose from over 15 examples and deploy with a single click.",
},
{
title: "Deploy",
href: "https://vercel.com/new",
description:
" Instantly deploy your Turborepo to a shareable URL with Vercel.",
},
];
export default function Page(): JSX.Element {
return (
<main className={styles.main}>
<div className={styles.description}>
<p>
examples/basic&nbsp;
<code className={styles.code}>web</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-turbo&utm_medium=basic&utm_campaign=create-turbo"
rel="noopener noreferrer"
target="_blank"
>
By{" "}
<Image
alt="Vercel Logo"
className={styles.vercelLogo}
height={24}
priority
src="/vercel.svg"
width={100}
/>
</a>
</div>
</div>
<div className={styles.hero}>
<div className={styles.heroContent}>
<div className={styles.logos}>
<div className={styles.circles}>
<Image
alt="Turborepo"
height={614}
src="circles.svg"
width={614}
/>
</div>
<div className={styles.logoGradientContainer}>
<Gradient className={styles.logoGradient} conic small />
</div>
<div className={styles.logo}>
<Image
alt=""
height={120}
priority
src="turborepo.svg"
width={120}
/>
</div>
</div>
<Gradient className={styles.backgroundGradient} conic />
<div className={styles.turborepoWordmarkContainer}>
<svg
className={styles.turborepoWordmark}
viewBox="0 0 506 50"
width={200}
xmlns="http://www.w3.org/2000/svg"
>
<title>Turborepo logo</title>
<path d="M53.7187 12.0038V1.05332H0.945312V12.0038H20.8673V48.4175H33.7968V12.0038H53.7187Z" />
<path d="M83.5362 49.1431C99.764 49.1431 108.67 40.8972 108.67 27.3081V1.05332H95.7401V26.0547C95.7401 33.6409 91.7821 37.9287 83.5362 37.9287C75.2904 37.9287 71.3324 33.6409 71.3324 26.0547V1.05332H58.4029V27.3081C58.4029 40.8972 67.3084 49.1431 83.5362 49.1431Z" />
<path d="M128.462 32.7174H141.325L151.484 48.4175H166.327L154.848 31.3321C161.313 29.0232 165.271 23.8778 165.271 16.8853C165.271 6.72646 157.685 1.05332 146.141 1.05332H115.532V48.4175H128.462V32.7174ZM128.462 22.4925V11.8719H145.481C150.033 11.8719 152.54 13.8509 152.54 17.2152C152.54 20.3816 150.033 22.4925 145.481 22.4925H128.462Z" />
<path d="M171.287 48.4175H205.128C215.683 48.4175 221.752 43.404 221.752 35.0262C221.752 29.419 218.189 25.593 213.967 23.8778C216.87 22.4925 220.432 19.1942 220.432 13.9828C220.432 5.60502 214.495 1.05332 204.006 1.05332H171.287V48.4175ZM183.689 19.59V11.542H202.687C206.249 11.542 208.228 12.9273 208.228 15.566C208.228 18.2047 206.249 19.59 202.687 19.59H183.689ZM183.689 29.2871H203.875C207.371 29.2871 209.284 31.0022 209.284 33.5749C209.284 36.1476 207.371 37.8628 203.875 37.8628H183.689V29.2871Z" />
<path d="M253.364 0.261719C236.806 0.261719 224.866 10.6185 224.866 24.7354C224.866 38.8523 236.806 49.2091 253.364 49.2091C269.922 49.2091 281.796 38.8523 281.796 24.7354C281.796 10.6185 269.922 0.261719 253.364 0.261719ZM253.364 11.4761C262.072 11.4761 268.602 16.6215 268.602 24.7354C268.602 32.8493 262.072 37.9947 253.364 37.9947C244.656 37.9947 238.126 32.8493 238.126 24.7354C238.126 16.6215 244.656 11.4761 253.364 11.4761Z" />
<path d="M300.429 32.7174H313.292L323.451 48.4175H338.294L326.815 31.3321C333.28 29.0232 337.238 23.8778 337.238 16.8853C337.238 6.72646 329.652 1.05332 318.108 1.05332H287.499V48.4175H300.429V32.7174ZM300.429 22.4925V11.8719H317.448C322 11.8719 324.507 13.8509 324.507 17.2152C324.507 20.3816 322 22.4925 317.448 22.4925H300.429Z" />
<path d="M343.254 1.05332V48.4175H389.299V37.467H355.92V29.7489H385.539V19.0622H355.92V12.0038H389.299V1.05332H343.254Z" />
<path d="M408.46 33.3111H425.677C437.221 33.3111 444.807 27.7699 444.807 17.2152C444.807 6.59453 437.221 1.05332 425.677 1.05332H395.53V48.4175H408.46V33.3111ZM408.46 22.5585V11.8719H424.951C429.569 11.8719 432.076 13.8509 432.076 17.2152C432.076 20.5135 429.569 22.5585 424.951 22.5585H408.46Z" />
<path d="M476.899 0.261719C460.341 0.261719 448.401 10.6185 448.401 24.7354C448.401 38.8523 460.341 49.2091 476.899 49.2091C493.456 49.2091 505.33 38.8523 505.33 24.7354C505.33 10.6185 493.456 0.261719 476.899 0.261719ZM476.899 11.4761C485.606 11.4761 492.137 16.6215 492.137 24.7354C492.137 32.8493 485.606 37.9947 476.899 37.9947C468.191 37.9947 461.66 32.8493 461.66 24.7354C461.66 16.6215 468.191 11.4761 476.899 11.4761Z" />
</svg>
</div>
</div>
</div>
<div className={styles.grid}>
{LINKS.map(({ title, href, description }) => (
<Card className={styles.card} href={href} key={title} title={title}>
{description}
</Card>
))}
</div>
</main>
);
}

5
apps/web/next-env.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

4
apps/web/next.config.js Normal file
View file

@ -0,0 +1,4 @@
module.exports = {
reactStrictMode: true,
transpilePackages: ["ui"],
};

26
apps/web/package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "web",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ui": "workspace:*"
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.4.19",
"@types/node": "^17.0.12",
"@types/react": "^18.0.22",
"@types/react-dom": "^18.0.7",
"eslint-config-custom": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "^4.5.3"
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="614" height="614">
<defs xmlns="http://www.w3.org/2000/svg">
<radialGradient id="radial" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fff"></stop>
<stop offset="60%" stop-color="#fff" stop-opacity="0"></stop>
</radialGradient>
</defs>
<circle cx="50" cy="50" r="25" stroke-width=".2" style="fill:none; stroke:rgba(255,255,255,.1);">
<animate attributeName="opacity" values="1;0.1;0.1;1" dur="3s" begin="0.2s" repeatCount="indefinite"></animate>
</circle>
<circle cx="50" cy="50" r="25" stroke-width=".2" style="fill:url(#radial); fill-opacity:.1;">
<animate attributeName="opacity" values="1;0.5;0.5;1" dur="3s" repeatCount="indefinite"></animate>
</circle><circle cx="50" cy="50" r="45" stroke-width=".2" style="fill:none; stroke:rgba(255,255,255,.1);">
<animate attributeName="opacity" values="1;0.1;0.1;1" dur="3s" begin="0.4s" repeatCount="indefinite"></animate>
</circle>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
apps/web/public/next.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,32 @@
<svg width="104" height="104" viewBox="0 0 104 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_17)">
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="black" fill-opacity="0.64"/>
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="url(#paint0_linear_1_17)" fill-opacity="0.15"/>
<path d="M26.0192 7C42.0962 -2.28203 61.9038 -2.28203 77.9808 7C94.0577 16.282 103.962 33.4359 103.962 52C103.962 70.5641 94.0577 87.718 77.9808 97C61.9038 106.282 42.0962 106.282 26.0192 97C9.94229 87.718 0.038475 70.5641 0.038475 52C0.038475 33.4359 9.94229 16.282 26.0192 7Z" fill="black" fill-opacity="0.5"/>
<path d="M0.538475 52C0.538475 33.6146 10.347 16.6257 26.2692 7.43301C42.1915 -1.7597 61.8085 -1.7597 77.7308 7.43301C93.653 16.6257 103.462 33.6146 103.462 52C103.462 70.3854 93.653 87.3743 77.7308 96.567C61.8085 105.76 42.1915 105.76 26.2692 96.567C10.347 87.3743 0.538475 70.3854 0.538475 52Z" stroke="url(#paint1_radial_1_17)" stroke-opacity="0.15"/>
<path d="M0.538475 52C0.538475 33.6146 10.347 16.6257 26.2692 7.43301C42.1915 -1.7597 61.8085 -1.7597 77.7308 7.43301C93.653 16.6257 103.462 33.6146 103.462 52C103.462 70.3854 93.653 87.3743 77.7308 96.567C61.8085 105.76 42.1915 105.76 26.2692 96.567C10.347 87.3743 0.538475 70.3854 0.538475 52Z" stroke="url(#paint2_linear_1_17)" stroke-opacity="0.5"/>
<path d="M51.8878 37.9262C44.1892 37.9262 37.9258 44.1896 37.9258 51.8882C37.9258 59.5868 44.1892 65.8502 51.8878 65.8502C59.5864 65.8502 65.8498 59.5868 65.8498 51.8882C65.8498 44.1896 59.5864 37.9262 51.8878 37.9262ZM51.8878 59.1136C47.8968 59.1136 44.6624 55.8792 44.6624 51.8882C44.6624 47.8972 47.8968 44.6628 51.8878 44.6628C55.8788 44.6628 59.1132 47.8972 59.1132 51.8882C59.1132 55.8792 55.8788 59.1136 51.8878 59.1136Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0581 35.633V30.42C64.3889 31.0258 73.3901 40.4066 73.3901 51.8882C73.3901 63.3698 64.3889 72.748 53.0581 73.3564V68.1434C61.5029 67.5402 68.1901 60.4838 68.1901 51.8882C68.1901 43.2926 61.5029 36.2362 53.0581 35.633ZM39.5745 62.5482C37.3359 59.9638 35.8929 56.6722 35.6355 53.0582H30.4199C30.6903 58.1152 32.7131 62.7042 35.8825 66.2376L39.5719 62.5482H39.5745ZM50.7182 73.3564V68.1434C47.1016 67.886 43.81 66.4456 41.2256 64.2044L37.5362 67.8938C41.0722 71.0658 45.6612 73.086 50.7156 73.3564H50.7182Z" fill="url(#paint3_linear_1_17)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1_17" x1="52" y1="-8" x2="52" y2="112" gradientUnits="userSpaceOnUse">
<stop stop-color="#3286F1"/>
<stop offset="1" stop-color="#C43AC4"/>
</linearGradient>
<radialGradient id="paint1_radial_1_17" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(52 -7.99999) rotate(90) scale(154.286 154.286)">
<stop stop-color="white"/>
<stop offset="1" stop-color="white"/>
</radialGradient>
<linearGradient id="paint2_linear_1_17" x1="-8" y1="-8" x2="18.25" y2="40.75" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_1_17" x1="53.9007" y1="33.4389" x2="32.7679" y2="54.5717" gradientUnits="userSpaceOnUse">
<stop stop-color="#0096FF"/>
<stop offset="1" stop-color="#FF1E56"/>
</linearGradient>
<clipPath id="clip0_1_17">
<rect width="104" height="104" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

8
apps/web/tsconfig.json Normal file
View file

@ -0,0 +1,8 @@
{
"extends": "tsconfig/nextjs.json",
"compilerOptions": {
"plugins": [{ "name": "next" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

17
package.json Normal file
View file

@ -0,0 +1,17 @@
{
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"devDependencies": {
"eslint": "^8.48.0",
"prettier": "^3.0.3",
"tsconfig": "workspace:*",
"turbo": "latest"
},
"packageManager": "pnpm@8.6.10",
"name": "hostforge"
}

View file

@ -0,0 +1,3 @@
# `@turbo/eslint-config`
Collection of internal eslint configurations.

View file

@ -0,0 +1,34 @@
const { resolve } = require("node:path");
const project = resolve(process.cwd(), "tsconfig.json");
/*
* This is a custom ESLint configuration for use with
* typescript packages.
*
* This config extends the Vercel Engineering Style Guide.
* For more information, see https://github.com/vercel/style-guide
*
*/
module.exports = {
extends: [
"@vercel/style-guide/eslint/node",
"@vercel/style-guide/eslint/typescript",
].map(require.resolve),
parserOptions: {
project,
},
globals: {
React: true,
JSX: true,
},
settings: {
"import/resolver": {
typescript: {
project,
},
},
},
ignorePatterns: ["node_modules/", "dist/"],
};

View file

@ -0,0 +1,42 @@
const { resolve } = require("node:path");
const project = resolve(process.cwd(), "tsconfig.json");
/*
* This is a custom ESLint configuration for use with
* Next.js apps.
*
* This config extends the Vercel Engineering Style Guide.
* For more information, see https://github.com/vercel/style-guide
*
*/
module.exports = {
extends: [
"@vercel/style-guide/eslint/node",
"@vercel/style-guide/eslint/typescript",
"@vercel/style-guide/eslint/browser",
"@vercel/style-guide/eslint/react",
"@vercel/style-guide/eslint/next",
"eslint-config-turbo",
].map(require.resolve),
parserOptions: {
project,
},
globals: {
React: true,
JSX: true,
},
settings: {
"import/resolver": {
typescript: {
project,
},
},
},
ignorePatterns: ["node_modules/", "dist/"],
// add rules configurations here
rules: {
"import/no-default-export": "off",
},
};

View file

@ -0,0 +1,10 @@
{
"name": "eslint-config-custom",
"license": "MIT",
"version": "0.0.0",
"private": true,
"devDependencies": {
"@vercel/style-guide": "^5.0.0",
"eslint-config-turbo": "^1.10.12"
}
}

View file

@ -0,0 +1,39 @@
const { resolve } = require("node:path");
const project = resolve(process.cwd(), "tsconfig.json");
/*
* This is a custom ESLint configuration for use with
* internal (bundled by their consumer) libraries
* that utilize React.
*
* This config extends the Vercel Engineering Style Guide.
* For more information, see https://github.com/vercel/style-guide
*
*/
module.exports = {
extends: [
"@vercel/style-guide/eslint/browser",
"@vercel/style-guide/eslint/typescript",
"@vercel/style-guide/eslint/react",
].map(require.resolve),
parserOptions: {
project,
},
globals: {
JSX: true,
},
settings: {
"import/resolver": {
typescript: {
project,
},
},
},
ignorePatterns: ["node_modules/", "dist/", ".eslintrc.js"],
rules: {
// add specific rules configurations here
},
};

View file

@ -0,0 +1,21 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true,
"strictNullChecks": true
},
"exclude": ["node_modules"]
}

View file

@ -0,0 +1,21 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Next.js",
"extends": "./base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"allowJs": true,
"declaration": false,
"declarationMap": false,
"incremental": true,
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"noEmit": true,
"resolveJsonModule": true,
"strict": false,
"target": "es5"
},
"include": ["src", "next-env.d.ts"],
"exclude": ["node_modules"]
}

View file

@ -0,0 +1,9 @@
{
"name": "tsconfig",
"version": "0.0.0",
"private": true,
"license": "MIT",
"publishConfig": {
"access": "public"
}
}

View file

@ -0,0 +1,11 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "React Library",
"extends": "./base.json",
"compilerOptions": {
"jsx": "react-jsx",
"lib": ["ES2015", "DOM"],
"module": "ESNext",
"target": "es6"
}
}

3
packages/ui/.eslintrc.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
extends: ["custom/react-internal"],
};

27
packages/ui/card.tsx Normal file
View file

@ -0,0 +1,27 @@
import * as React from "react";
export function Card({
className,
title,
children,
href,
}: {
className?: string;
title: string;
children: React.ReactNode;
href: string;
}): JSX.Element {
return (
<a
className={className}
href={`${href}?utm_source=create-turbo&utm_medium=basic&utm_campaign=create-turbo"`}
rel="noopener noreferrer"
target="_blank"
>
<h2>
{title} <span>-&gt;</span>
</h2>
<p>{children}</p>
</a>
);
}

2
packages/ui/index.tsx Normal file
View file

@ -0,0 +1,2 @@
// component exports
export { Card } from "./card";

21
packages/ui/package.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "ui",
"version": "0.0.0",
"main": "./index.tsx",
"types": "./index.tsx",
"license": "MIT",
"scripts": {
"lint": "eslint .",
"generate:component": "turbo gen react-component"
},
"devDependencies": {
"@turbo/gen": "^1.10.12",
"@types/node": "^20.5.2",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"eslint-config-custom": "workspace:*",
"react": "^18.2.0",
"tsconfig": "workspace:*",
"typescript": "^4.5.2"
}
}

View file

@ -0,0 +1,5 @@
{
"extends": "tsconfig/react-library.json",
"include": ["."],
"exclude": ["dist", "build", "node_modules"]
}

View file

@ -0,0 +1,31 @@
import type { PlopTypes } from "@turbo/gen";
// Learn more about Turborepo Generators at https://turbo.build/repo/docs/core-concepts/monorepos/code-generation
// eslint-disable-next-line import/no-default-export -- Turbo generators require default export
export default function generator(plop: PlopTypes.NodePlopAPI): void {
// A simple generator to add a new React component to the internal UI library
plop.setGenerator("react-component", {
description: "Adds a new react component",
prompts: [
{
type: "input",
name: "name",
message: "What is the name of the component?",
},
],
actions: [
{
type: "add",
path: "{{pascalCase name}}.tsx",
templateFile: "templates/component.hbs",
},
{
type: "append",
path: "index.tsx",
pattern: /(?<insertion>\/\/ component exports)/g,
template: 'export * from "./{{pascalCase name}}";',
},
],
});
}

View file

@ -0,0 +1,14 @@
import * as React from "react";
interface Props {
children?: React.ReactNode;
}
export const {{ pascalCase name }} = ({ children }: Props) => {
return (
<div>
<h1>{{ name }}</h1>
{children}
</div>
);
};

4709
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load diff

3
pnpm-workspace.yaml Normal file
View file

@ -0,0 +1,3 @@
packages:
- "apps/*"
- "packages/*"

3
tsconfig.json Normal file
View file

@ -0,0 +1,3 @@
{
"extends": "tsconfig/base.json"
}

15
turbo.json Normal file
View file

@ -0,0 +1,15 @@
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}