>(({ className, ...props }, ref) => (
| [role=checkbox]]:translate-y-[2px]",
className,
)}
{...props}
/>
));
TableCell.displayName = "TableCell";
const TableCaption = React.forwardRef<
HTMLTableCaptionElement,
React.HTMLAttributes
>(({ className, ...props }, ref) => (
));
TableCaption.displayName = "TableCaption";
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
};
================================================
FILE: apps/web/components/ui/textarea.tsx
================================================
import * as React from "react";
import { cn } from "@/lib/utils/common";
export interface TextareaProps
extends React.TextareaHTMLAttributes {}
const Textarea = React.forwardRef(
({ className, ...props }, ref) => {
return (
);
},
);
Textarea.displayName = "Textarea";
export { Textarea };
================================================
FILE: apps/web/components.json
================================================
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils/common"
}
}
================================================
FILE: apps/web/content/community-digest-summer-edition.mdx
================================================
---
title: 'Community Digest: Summer Edition'
publishedAt: '2020-07-09'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Lisa Allison'
authorImg: '/images/news-author-01.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/create-and-deploy-a-blog-with-simple.mdx
================================================
---
title: 'Create and Deploy a blog with Simple'
publishedAt: '2020-07-20'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Micheal Osman'
authorImg: '/images/news-author-04.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/getting-started-with-nextjs.mdx
================================================
---
title: 'Getting started with Next.js'
publishedAt: '2020-07-19'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Lisa Allison'
authorImg: '/images/news-author-01.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/getting-started-with-vuejs-and-stripe.mdx
================================================
---
title: 'Getting started with Vue.js and Stripe'
publishedAt: '2020-07-15'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Justin Park'
authorImg: '/images/news-author-03.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/how-to-identify-high-intent-leads.mdx
================================================
---
title: 'How to identify high-intent leads'
publishedAt: '2020-07-18'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Knut Mayer'
authorImg: '/images/news-author-02.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/how-to-work-with-friendly-apis.mdx
================================================
---
title: 'How to work with friendly APIs'
publishedAt: '2020-07-14'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Lisa Allison'
authorImg: '/images/news-author-01.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/introducing-the-testing-field-guide.mdx
================================================
---
title: 'Introducing the Testing Field Guide'
publishedAt: '2020-07-12'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Cory McCall'
authorImg: '/images/news-author-06.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/content/why-we-think-simple-is-good-for-developers.mdx
================================================
---
title: 'Why we think Simple is good for developers'
publishedAt: '2020-07-17'
summary: 'In this post, you will learn how to deploy a blog using Simple custom asset source plugin that uses the webcam to insert a photo in the image field.'
author: 'Micheal Osman'
authorImg: '/images/news-author-04.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis enim lobortis scelerisque fermentum. Neque sodales ut etiam sit amet [how to manage anything](#0) malesuada proin libero nunc consequat interdum varius. Quam pellentesque nec nam aliquam sem **et tortor consequat**. Pellentesque adipiscing commodo elit at imperdiet. Semper auctor neque vitae tempus quam pellentesque nec. Amet dictum sit amet justo donec enim diam. **Varius sit amet mattis vulputate enim** nulla aliquet porttitor. Odio pellentesque diam volutpat commodo sed. Elit sed vulputate mi sit amet mauris commodo quis imperdiet.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
## General content
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet. Morbi tristique senectus et netus et, nibh nisl condimentum id venenatis a condimentum vitae sapien.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
* **E-commerce**: Better lorem ipsum generator.
* **Booking**: Lorem ipsum post generator.
* **Retail**: Generic dummy blog post generator.
* **On-demand services**: Lorem ipsum generator shortcode.
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
[Read Simple on-demand services](#0)
## Additional reading
Aenean sed adipiscing _diam donec adipiscing tristique risus nec feugiat_ auctor urna nunc id cursus metus aliquam eleifend, arcu dictum varius duis at consectetur lorem donec massa sapien, sed risus ultricies tristique nulla aliquet.
#### Why support for Business is important
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend.
> Mi in nulla posuere sollicitudin. Porttitor eget dolor morbi non arcu risus quis varius quam. Pharetra vel turpis nunc eget lorem dolor sed viverra. Semper auctor neque vitae tempus quam pellentesque nec.
Et leo duis ut diam quam nulla porttitor porttitor lacus luctus accumsan tortor, lorem dolor sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam.
[Simple](#0) is a sed viverra ipsum nunc aliquet bibendum enim eu augue ut lectus arcu bibendum at. Non sodales neque sodales ut etiam sit. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Learn more [here](#0).
Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat auctor urna nunc id cursus metus aliquam eleifend:
**Mi in nulla posuere sollicitudin:**
* [E-commerce for etter lorem ipsum generator](#0)
* [Booking for lorem ipsum post generator](#0)
* [Retail for generic dummy blog post generator](#0)
* [On-demand services: Lorem ipsum generator shortcode](#0)
## Conclusion
Sollicitudin ac orci phasellus egestas tellus rutrum telluse nim ut tellus elementum sagittis vitae et leo duis egestas purus viverra accumsan in nisl nisi scelerisquep ellentesque habitant morbi tristique, senectus et netus et dolor purus non enim praesent elementum facilisis leol, aoreet suspendisse interdum consectetur libero id faucibus.
================================================
FILE: apps/web/contentlayer.config.js
================================================
import { defineDocumentType, makeSource } from "contentlayer/source-files";
import rehypeSlug from "rehype-slug";
const Post = defineDocumentType(() => ({
name: "Post",
filePathPattern: `**/*.mdx`,
contentType: "mdx",
fields: {
title: {
type: "string",
required: true,
},
publishedAt: {
type: "date",
required: true,
},
summary: {
type: "string",
required: true,
},
author: {
type: "string",
required: true,
},
authorImg: {
type: "string",
required: true,
},
},
computedFields: {
slug: {
type: "string",
resolve: doc => doc._raw.flattenedPath,
},
},
}));
export default makeSource({
contentDirPath: "content",
documentTypes: [Post],
mdx: {
rehypePlugins: [rehypeSlug],
},
});
================================================
FILE: apps/web/core/constants/configs.ts
================================================
const isProduction = process.env.NODE_ENV === "production";
export const configuration = {
site: {
name: "Captable",
description: "Open source cap table management software",
image: "/assets/hero.png",
themeColor: "#ffffff",
themeColorDark: "#0a0a0a",
siteUrl: process.env.NEXT_PUBLIC_SITE_URL,
siteName: "Captable",
twitterHandle: "octolane_app",
githubHandle: "octolane-org",
},
isProduction,
environment: process.env.NEXT_PUBLIC_ENVIRONMENT,
octolaneAPIKey: process.env.OCTOLANE_API_KEY,
sentry: {
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
},
posthog: {
apiKey: process.env.NEXT_PUBLIC_POSTHOG_API_KEY,
apiHost: process.env.NEXT_PUBLIC_POSTHOG_API_HOST,
},
auth: {
secret: process.env.NEXTAUTH_SECRET as string,
google: {
clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
metaphoreApiKey: process.env.METAPHOR_API_KEY,
openaiApiKey: process.env.OPENAI_API_KEY,
youApiKey: process.env.YOU_API as string,
paths: {
dashbord: "/dashboard",
signin: "/signin",
signup: "/signup",
capTables: { all: "/dashboard/cap-table", new: "cap-table/new" },
equityPlans: { all: "/dashboard/equity-plans", new: "equity-plans/new" },
shareClasses: { all: "/dashboard/share-classes", new: "share-classes/new" },
valuation401A: "/dashboard/401-a",
rule701: "/dashboard/rule-701",
settings: "/dashboard/settings",
},
};
export const FINGERPRINT_HEADER = "x-fingerprint";
export const X_CSRF_TOKEN_HEADER = "X-CSRF-Token";
================================================
FILE: apps/web/core/prisma.ts
================================================
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();
================================================
FILE: apps/web/core/types/common.type.ts
================================================
export type ObjectString = Record;
export type ValueOf = T[keyof T];
export type ServerPageProps = {
params: Params;
searchParams: SearchParams;
};
export type ReactComponentProps> =
React.PropsWithChildren;
================================================
FILE: apps/web/global.d.ts
================================================
declare global {
type StringObject = Record;
type NumberObject = Record;
type UnknownObject = Record;
type BooleanObject = Record;
type UnixTimestamp = number;
type WithId = T & {
id: number | string;
};
type Truthy = false extends T
? never
: 0 extends T
? never
: "" extends T
? never
: null extends T
? never
: undefined extends T
? never
: T;
type Falsy = false | 0 | "" | null | undefined;
type Maybe = T | undefined;
type EmptyCallback = () => void;
type HttpMethod = `GET` | `POST` | `PUT` | "PATCH" | "DELETE" | "HEAD";
}
declare module "react" {
type FCC> = React.FC<
React.PropsWithChildren
>;
}
export {};
================================================
FILE: apps/web/lib/server/session.ts
================================================
import { nextAuthOptions } from "@/app/api/auth/[...nextauth]/options";
import { HttpStatusCode } from "axios";
import { getServerSession } from "next-auth";
export const checkServerSession = async () => {
const session = await getServerSession(nextAuthOptions);
if (!session || !session.user) {
return Response.json(
{ message: "You are not authenticated" },
{ status: HttpStatusCode.Unauthorized },
);
}
return session;
};
export const getCurrentUser = async () => {
const session = await getServerSession(nextAuthOptions);
if (!session || !session.user) {
return null;
}
return session.user;
};
================================================
FILE: apps/web/lib/utils/common.ts
================================================
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export const formatCurrency = (value: number) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(value);
};
================================================
FILE: apps/web/next.config.js
================================================
const { withContentlayer } = require('next-contentlayer')
/** @type {import('next').NextConfig} */
const nextConfig = {}
module.exports = withContentlayer(nextConfig)
================================================
FILE: apps/web/package.json
================================================
{
"name": "cap.octolane.com",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "concurrently --kill-others \"prisma generate && next dev --port 5897\" \"prisma studio --browser none\"",
"build": "prisma generate & next build",
"format:write": "prettier --write \"**/*.{css,js,json,jsx,ts,tsx}\"",
"format": "prettier \"**/*.{css,js,json,jsx,ts,tsx}\"",
"lint": "next lint",
"start": "next start",
"script": "tsx ./scripts/run.ts"
},
"overrides": {
"next-contentlayer": {
"next": "$next"
}
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.5.1",
"@fortawesome/free-brands-svg-icons": "6.5.1",
"@fortawesome/free-solid-svg-icons": "6.5.1",
"@fortawesome/react-fontawesome": "0.2.0",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "2.1.1",
"@hookform/resolvers": "3.3.4",
"@next-auth/prisma-adapter": "1.0.7",
"@prisma/client": "5.8.0",
"@radix-ui/react-icons": "1.3.0",
"@radix-ui/react-label": "2.0.2",
"@radix-ui/react-popover": "1.0.7",
"@radix-ui/react-radio-group": "1.1.3",
"@radix-ui/react-select": "2.0.0",
"@radix-ui/react-slot": "1.0.2",
"@radix-ui/react-switch": "1.0.3",
"@types/node": "^20.10.4",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"@vercel/analytics": "1.1.1",
"aos": "^3.0.0-beta.6",
"axios": "1.6.5",
"class-variance-authority": "0.7.0",
"clsx": "2.1.0",
"concurrently": "8.2.2",
"contentlayer": "^0.3.2",
"date-fns": "^2.30.0",
"next": "^14.1.1",
"next-auth": "4.24.5",
"next-contentlayer": "^0.3.4",
"prisma": "5.8.0",
"react": "18.2.0",
"react-day-picker": "8.10.0",
"react-dom": "18.2.0",
"react-hook-form": "7.49.3",
"rehype-slug": "^6.0.0",
"solid": "link:@heroicons/react/20/solid",
"sonner": "1.3.1",
"tailwind-merge": "2.2.0",
"tailwindcss-animate": "1.0.7",
"typescript": "^5.3.3",
"yup": "1.3.3",
"zod": "3.22.4"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10",
"@trivago/prettier-plugin-sort-imports": "4.3.0",
"@types/aos": "^3.0.7",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.32",
"tailwindcss": "^3.3.6"
}
}
================================================
FILE: apps/web/postcss.config.js
================================================
module.exports = {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
},
};
================================================
FILE: apps/web/prisma/migrations/20240110170446_nextauth_schema/migration.sql
================================================
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"name" TEXT,
"email" TEXT,
"emailVerified" TIMESTAMP(3),
"image" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"providerAccountId" TEXT NOT NULL,
"refresh_token" TEXT,
"access_token" TEXT,
"expires_at" INTEGER,
"token_type" TEXT,
"scope" TEXT,
"id_token" TEXT,
"session_state" TEXT,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"sessionToken" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "VerificationToken" (
"identifier" TEXT NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL
);
-- CreateTable
CREATE TABLE "Token" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"hashedKey" TEXT NOT NULL,
"partialKey" TEXT NOT NULL,
"expires" TIMESTAMP(3),
"lastUsed" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"userId" TEXT NOT NULL,
CONSTRAINT "Token_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE INDEX "Account_userId_idx" ON "Account"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
-- CreateIndex
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
-- CreateIndex
CREATE INDEX "Session_userId_idx" ON "Session"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
-- CreateIndex
CREATE UNIQUE INDEX "Token_hashedKey_key" ON "Token"("hashedKey");
-- CreateIndex
CREATE INDEX "Token_userId_idx" ON "Token"("userId");
================================================
FILE: apps/web/prisma/migrations/20240110175417_basic_captable/migration.sql
================================================
/*
Warnings:
- Added the required column `companyId` to the `User` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "User" ADD COLUMN "companyId" TEXT NOT NULL,
ADD COLUMN "role" TEXT;
-- CreateTable
CREATE TABLE "Company" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"industry" TEXT,
"incorporationDate" TIMESTAMP(3),
CONSTRAINT "Company_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "EquityInstrument" (
"id" SERIAL NOT NULL,
"type" TEXT NOT NULL,
"totalIssued" INTEGER NOT NULL,
"companyId" TEXT NOT NULL,
CONSTRAINT "EquityInstrument_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Shareholder" (
"id" SERIAL NOT NULL,
"userId" TEXT NOT NULL,
"shareholderType" TEXT NOT NULL,
CONSTRAINT "Shareholder_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Shareholding" (
"id" SERIAL NOT NULL,
"shareholderId" INTEGER NOT NULL,
"instrumentId" INTEGER NOT NULL,
"sharesOwned" INTEGER NOT NULL,
"acquisitionDate" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Shareholding_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Transaction" (
"id" SERIAL NOT NULL,
"shareholdingId" INTEGER NOT NULL,
"transactionDate" TIMESTAMP(3) NOT NULL,
"sharesTransferred" INTEGER NOT NULL,
"transactionType" TEXT NOT NULL,
CONSTRAINT "Transaction_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CapTable" (
"id" SERIAL NOT NULL,
"companyId" TEXT NOT NULL,
"snapshotDate" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CapTable_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "EquityInstrument_companyId_idx" ON "EquityInstrument"("companyId");
-- CreateIndex
CREATE INDEX "Shareholder_userId_idx" ON "Shareholder"("userId");
-- CreateIndex
CREATE INDEX "Shareholding_shareholderId_idx" ON "Shareholding"("shareholderId");
-- CreateIndex
CREATE INDEX "Shareholding_instrumentId_idx" ON "Shareholding"("instrumentId");
-- CreateIndex
CREATE INDEX "Transaction_shareholdingId_idx" ON "Transaction"("shareholdingId");
-- CreateIndex
CREATE INDEX "CapTable_companyId_idx" ON "CapTable"("companyId");
-- CreateIndex
CREATE INDEX "User_companyId_idx" ON "User"("companyId");
================================================
FILE: apps/web/prisma/migrations/20240111041700_remove_relation_mode/migration.sql
================================================
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EquityInstrument" ADD CONSTRAINT "EquityInstrument_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Shareholder" ADD CONSTRAINT "Shareholder_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Shareholding" ADD CONSTRAINT "Shareholding_shareholderId_fkey" FOREIGN KEY ("shareholderId") REFERENCES "Shareholder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Shareholding" ADD CONSTRAINT "Shareholding_instrumentId_fkey" FOREIGN KEY ("instrumentId") REFERENCES "EquityInstrument"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Transaction" ADD CONSTRAINT "Transaction_shareholdingId_fkey" FOREIGN KEY ("shareholdingId") REFERENCES "Shareholding"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CapTable" ADD CONSTRAINT "CapTable_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
================================================
FILE: apps/web/prisma/migrations/20240111055724_remove_company_as_notnullable_from_user_table/migration.sql
================================================
-- DropForeignKey
ALTER TABLE "User" DROP CONSTRAINT "User_companyId_fkey";
-- AlterTable
ALTER TABLE "User" ALTER COLUMN "companyId" DROP NOT NULL;
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
================================================
FILE: apps/web/prisma/migrations/migration_lock.toml
================================================
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
================================================
FILE: apps/web/prisma/schema.prisma
================================================
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch", "fullTextIndex"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
// relationMode = "prisma"
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
role String?
company Company? @relation(fields: [companyId], references: [id])
companyId String?
accounts Account[]
sessions Session[]
tokens Token[]
createdAt DateTime @default(now())
Shareholder Shareholder[]
@@index([companyId])
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@index([userId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model Token {
id String @id @default(cuid())
name String
hashedKey String @unique
partialKey String
expires DateTime?
lastUsed DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
@@index([userId])
}
model Company {
id String @id @default(cuid())
name String
industry String?
incorporationDate DateTime?
users User[]
equityInstruments EquityInstrument[]
capTables CapTable[]
}
model EquityInstrument {
id Int @id @default(autoincrement())
type String
totalIssued Int
company Company @relation(fields: [companyId], references: [id])
companyId String
shareholdings Shareholding[]
@@index([companyId])
}
model Shareholder {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId String
shareholderType String
shareholdings Shareholding[]
@@index([userId])
}
model Shareholding {
id Int @id @default(autoincrement())
shareholder Shareholder @relation(fields: [shareholderId], references: [id])
shareholderId Int
instrument EquityInstrument @relation(fields: [instrumentId], references: [id])
instrumentId Int
sharesOwned Int
acquisitionDate DateTime
transactions Transaction[]
@@index([shareholderId])
@@index([instrumentId])
}
model Transaction {
id Int @id @default(autoincrement())
shareholding Shareholding @relation(fields: [shareholdingId], references: [id])
shareholdingId Int
transactionDate DateTime
sharesTransferred Int
transactionType String
@@index([shareholdingId])
}
model CapTable {
id Int @id @default(autoincrement())
company Company @relation(fields: [companyId], references: [id])
companyId String
snapshotDate DateTime
// Additional fields as needed
@@index([companyId])
}
================================================
FILE: apps/web/tailwind.config.js
================================================
const { fontFamily } = require("tailwindcss/defaultTheme");
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
prefix: "",
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
fontFamily: {
sans: ["var(--font-inter)", ...fontFamily.sans],
},
},
},
plugins: [require("tailwindcss-animate", "@tailwindcss/forms")],
};
================================================
FILE: apps/web/tsconfig.json
================================================
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": ".",
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"],
"contentlayer/generated": ["./.contentlayer/generated"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".contentlayer/generated"
],
"exclude": ["node_modules"]
}
================================================
FILE: docker-compose.yml
================================================
version: "3.7"
name: octolane-cap-table
services:
db:
image: postgres:16-alpine
container_name: postgres
mem_limit: 1g
ports:
- 5431:5432
environment:
POSTGRES_PASSWORD: randompassword
POSTGRES_DB: captable
POSTGRES_USER: username
volumes:
- /var/lib/postgresql/octolane-cap-table/data:/var/lib/postgresql/data
================================================
FILE: package.json
================================================
{
"name": "octolane-cap-monorepo",
"version": "1.0.0",
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"clean": "turbo clean",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"script": "echo 'Run this script in apps/web'",
"docker:start": "docker-compose up -d",
"prepare": "husky install && chmod +x .husky/pre-push && chmod +x .husky/pre-commit"
},
"repository": {
"type": "git",
"url": "git+https://github.com/octolane-org/cap.octolane.com.git"
},
"keywords": [
"Captable"
],
"author": "octolane-org",
"license": "AGPL-3.0-or-later",
"bugs": {
"url": "https://github.com/octolane-org/cap.octolane.com/issues"
},
"homepage": "https://github.com/octolane-org/cap.octolane.com#readme",
"devDependencies": {
"@types/hast": "^3.0.4",
"eslint": "9.8.0",
"prettier": "3.3.3",
"prettier-plugin-organize-imports": "4.0.0",
"prettier-plugin-tailwindcss": "0.6.5",
"turbo": "2.0.9"
},
"packageManager": "pnpm@8.6.10",
"dependencies": {
"husky": "9.1.4"
}
}
================================================
FILE: pnpm-workspace.yaml
================================================
packages:
- "apps/*"
================================================
FILE: turbo.json
================================================
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [
"**/.env"
],
"pipeline": {
"build": {
"dependsOn": [
"^build"
],
"outputs": [
"!.next/cache/**",
".next/**",
"dist/**"
]
},
"dev": {
"cache": false,
"persistent": true
},
"clean": {
"cache": false
}
}
} |