├── .cursor └── mcp.json ├── .gitignore ├── migrate ├── [slug] │ └── page.tsx ├── advent-calendar │ ├── advent-calendar │ │ ├── Card.tsx │ │ ├── Header.tsx │ │ └── Modal.tsx │ ├── head.txt │ ├── mint │ │ └── page.tsx │ └── page.tsx ├── blog │ ├── [slug] │ │ ├── head.txt │ │ └── page.tsx │ ├── head.txt │ ├── layout.txt │ └── page.txt ├── gas-fees-calculator │ └── page.tsx ├── playground │ └── page.dep ├── prompt-playground │ └── page.dep ├── register │ └── page.dep ├── search │ └── page.tsx ├── sign-in │ ├── layout.tsx │ └── page.tsx ├── web3-grants │ ├── AuthAlert.tsx │ ├── CategoryFilters.tsx │ ├── add │ │ ├── GrantForm.tsx │ │ └── GrantFormTally.tsx │ ├── edit │ │ ├── Modal.tsx │ │ └── ModalWrapper.tsx │ ├── grant │ │ ├── NoInfo.tsx │ │ ├── features.tsx │ │ ├── grant-info-card.tsx │ │ ├── grant-rfps.tsx │ │ └── header.tsx │ ├── quote.tsx │ ├── search │ │ ├── DesktopFilterOption.tsx │ │ ├── DesktopFilters.tsx │ │ ├── GrantCard.tsx │ │ ├── Header.tsx │ │ └── grant-columns.tsx │ ├── tbd-second-cta.tsx │ └── tbd-social-proof.tsx └── web3e-grants │ ├── (grant) │ └── [slug] │ │ ├── edit │ │ └── page.tsx │ │ └── page.tsx │ ├── add │ └── page.tsx │ ├── page.tsx │ └── search │ └── page.tsx └── packages ├── frontend ├── .contentlayer │ ├── .cache │ │ └── v0.3.4 │ │ │ ├── compiled-contentlayer-config-BAGCOISY.mjs │ │ │ ├── compiled-contentlayer-config-BAGCOISY.mjs.map │ │ │ └── data-BAGCOISY.json │ ├── generated │ │ ├── Author │ │ │ ├── _index.json │ │ │ ├── _index.mjs │ │ │ └── authors__felix-vemmer.mdx.json │ │ ├── Page │ │ │ ├── _index.json │ │ │ └── _index.mjs │ │ ├── Post │ │ │ ├── _index.json │ │ │ └── _index.mjs │ │ ├── index.d.ts │ │ ├── index.mjs │ │ └── types.d.ts │ └── package.json ├── .eslintignore ├── .eslintrc-back.json ├── .eslintrc.json ├── .gitignore ├── .npmrc ├── .prettierignore ├── README.md ├── components.json ├── content │ └── authors │ │ └── felix-vemmer.mdx ├── contentlayer.config.js ├── drizzle.config.ts ├── drizzle │ ├── 0000_nifty_mephistopheles.sql │ ├── 0001_aromatic_flatman.sql │ ├── 0002_sharp_kate_bishop.sql │ ├── 0003_light_the_twelve.sql │ ├── 0004_odd_thor.sql │ ├── 0005_early_maverick.sql │ ├── 0006_deep_harpoon.sql │ ├── 0007_friendly_cannonball.sql │ ├── 0008_first_luminals.sql │ ├── 0009_clammy_jane_foster.sql │ ├── 0010_absent_james_howlett.sql │ ├── 0011_watery_wildside.sql │ ├── 0012_fast_sir_ram.sql │ ├── 0013_breezy_taskmaster.sql │ ├── 0014_nebulous_klaw.sql │ ├── 0015_bizarre_lord_hawal.sql │ ├── 0016_vengeful_medusa.sql │ ├── 0017_jittery_weapon_omega.sql │ ├── 0018_real_magma.sql │ ├── 0019_exotic_norrin_radd.sql │ ├── 0020_robust_vision.sql │ ├── 0021_adorable_spencer_smythe.sql │ ├── 0022_bouncy_annihilus.sql │ ├── 0023_nappy_the_hood.sql │ ├── 0024_first_king_cobra.sql │ ├── 0025_fancy_gideon.sql │ ├── 0026_concerned_the_hunter.sql │ ├── 0027_volatile_dracula.sql │ └── meta │ │ ├── 0000_snapshot.json │ │ ├── 0001_snapshot.json │ │ ├── 0002_snapshot.json │ │ ├── 0003_snapshot.json │ │ ├── 0004_snapshot.json │ │ ├── 0005_snapshot.json │ │ ├── 0006_snapshot.json │ │ ├── 0007_snapshot.json │ │ ├── 0008_snapshot.json │ │ ├── 0009_snapshot.json │ │ ├── 0010_snapshot.json │ │ ├── 0011_snapshot.json │ │ ├── 0012_snapshot.json │ │ ├── 0013_snapshot.json │ │ ├── 0014_snapshot.json │ │ ├── 0015_snapshot.json │ │ ├── 0016_snapshot.json │ │ ├── 0017_snapshot.json │ │ ├── 0018_snapshot.json │ │ ├── 0019_snapshot.json │ │ ├── 0020_snapshot.json │ │ ├── 0021_snapshot.json │ │ ├── 0022_snapshot.json │ │ ├── 0023_snapshot.json │ │ ├── 0024_snapshot.json │ │ ├── 0025_snapshot.json │ │ ├── 0026_snapshot.json │ │ ├── 0027_snapshot.json │ │ └── _journal.json ├── i18n.ts ├── messages │ ├── de.json │ └── en.json ├── migrate.ts ├── next.config.js ├── package.json ├── postcss.config.js ├── prettier.config.js ├── public │ ├── VitalikButerin.jpg │ ├── advent-calendar │ │ ├── cover.png │ │ ├── vitalik1.png │ │ ├── vitalik10.png │ │ ├── vitalik11.png │ │ ├── vitalik12.png │ │ ├── vitalik13.png │ │ ├── vitalik14.png │ │ ├── vitalik15.png │ │ ├── vitalik16.png │ │ ├── vitalik17.png │ │ ├── vitalik18.png │ │ ├── vitalik19.png │ │ ├── vitalik2.png │ │ ├── vitalik20.png │ │ ├── vitalik21.png │ │ ├── vitalik22.png │ │ ├── vitalik23.png │ │ ├── vitalik24.png │ │ ├── vitalik3.png │ │ ├── vitalik4.png │ │ ├── vitalik5.png │ │ ├── vitalik6.png │ │ ├── vitalik7.png │ │ ├── vitalik8.png │ │ └── vitalik9.png │ ├── alarm-check.svg │ ├── favicon.ico │ ├── gas-fees-calculator │ │ ├── ogImag1.jpg │ │ └── ogImage2.jpg │ ├── logo_transparent.png │ ├── logos │ │ ├── Full_Logo_Black_Background.svg │ │ ├── Full_Logo_Main.svg │ │ ├── bertelsmann-stiftung.png │ │ ├── cryptoticker.png │ │ ├── deutsche-bank.png │ │ ├── gitcoinGrant.svg │ │ ├── lectura.png │ │ ├── monitor-deloitte.png │ │ ├── n26.png │ │ ├── power-zap-black.svg │ │ ├── priceloop.png │ │ ├── pwc.svg │ │ └── zapper-logo.png │ ├── networks │ │ ├── arbitrum_one_logo.jpeg │ │ ├── avalanche_logo.png │ │ ├── avalanche_logo.webp │ │ ├── binance_smart_chain_logo.png │ │ ├── celo_logo.png │ │ ├── ethereum_logo.png │ │ ├── fantom_logo.png │ │ ├── gnosis_logo.png │ │ ├── harmony_logo.png │ │ ├── loopring_logo.png │ │ ├── moonriver_logo.png │ │ ├── optimism_logo.jpeg │ │ ├── optimism_logo.png │ │ ├── polygon_logo.png │ │ ├── zksync_logo.jpeg │ │ └── zksync_logo.png │ ├── og │ │ └── web-3-grants │ │ │ ├── image1.jpg │ │ │ ├── image2.jpg │ │ │ └── image3.jpg │ ├── personal-projects │ │ ├── backlinkgpt-com.png │ │ ├── felixvemmer-com.png │ │ └── nocode-scraper-com.png │ ├── profilePic.jpg │ ├── quotes │ │ └── AwWgWl-Y_400x400.jpg │ └── vercel.svg ├── src │ ├── app │ │ ├── [locale] │ │ │ ├── (landing) │ │ │ │ ├── sign-in │ │ │ │ │ └── [[...sign-in]] │ │ │ │ │ │ └── page.tsx │ │ │ │ └── sign-up │ │ │ │ │ └── [[...sign-up]] │ │ │ │ │ └── page.tsx │ │ │ ├── about │ │ │ │ └── page.tsx │ │ │ ├── gas-fees-calculator │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── web3-grants │ │ │ │ ├── grants │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ └── navigation.ts │ ├── components │ │ ├── amazon-product-card.tsx │ │ ├── auth-clerk-header.tsx │ │ ├── cal-com.tsx │ │ ├── callout.tsx │ │ ├── code-block-wraper.tsx │ │ ├── column-defs │ │ │ └── grants.tsx │ │ ├── command-menu.tsx │ │ ├── data-table │ │ │ ├── advanced │ │ │ │ ├── data-table-advanced-faceted-filter.tsx │ │ │ │ ├── data-table-advanced-toolbar.tsx │ │ │ │ ├── data-table-filter-combobox.tsx │ │ │ │ ├── data-table-filter-item.tsx │ │ │ │ └── data-table-multi-filter.tsx │ │ │ ├── data-table-column-header.tsx │ │ │ ├── data-table-faceted-filter.tsx │ │ │ ├── data-table-pagination.tsx │ │ │ ├── data-table-row-actions.tsx │ │ │ ├── data-table-skeleton.tsx │ │ │ ├── data-table-toolbar.tsx │ │ │ ├── data-table-view-options.tsx │ │ │ └── data-table.tsx │ │ ├── featured.tsx │ │ ├── features.tsx │ │ ├── founders-note.tsx │ │ ├── gas-fees-calculator │ │ │ ├── currency-input.tsx │ │ │ ├── fees-form-card.tsx │ │ │ ├── fees-form.tsx │ │ │ ├── gas-price-radio.tsx │ │ │ ├── gitcoin-grant.tsx │ │ │ ├── share-buttons.tsx │ │ │ ├── table.tsx │ │ │ └── used-gas-input.tsx │ │ ├── icons copy.tsx │ │ ├── icons.tsx │ │ ├── iframe.tsx │ │ ├── language-toggle.tsx │ │ ├── link-button.tsx │ │ ├── main-nav.tsx │ │ ├── mdx-card.tsx │ │ ├── mdx-components.tsx │ │ ├── mobile-nav.tsx │ │ ├── mode-toggle.tsx │ │ ├── page-header.tsx │ │ ├── posthog-page-view.tsx │ │ ├── posthog-provider.tsx │ │ ├── providers.tsx │ │ ├── related-post-card.tsx │ │ ├── site-footer.tsx │ │ ├── site-header.tsx │ │ ├── tables │ │ │ └── grants.tsx │ │ ├── tailwind-indicator.tsx │ │ ├── testimonials.tsx │ │ ├── theme-provider.tsx │ │ ├── theme-switcher.tsx │ │ ├── toc.tsx │ │ ├── ui │ │ │ ├── accordion.tsx │ │ │ ├── alert-dialog.tsx │ │ │ ├── alert.tsx │ │ │ ├── aspect-ratio.tsx │ │ │ ├── avatar.tsx │ │ │ ├── badge.tsx │ │ │ ├── blockquote.tsx │ │ │ ├── border.tsx │ │ │ ├── button.tsx │ │ │ ├── calendar.tsx │ │ │ ├── card.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── collapsible.tsx │ │ │ ├── command.tsx │ │ │ ├── container.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── fade-in.tsx │ │ │ ├── form.tsx │ │ │ ├── grid-pattern.tsx │ │ │ ├── header.tsx │ │ │ ├── hover-card.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── list.tsx │ │ │ ├── menubar.tsx │ │ │ ├── navigation-menu.tsx │ │ │ ├── page-intro.tsx │ │ │ ├── popover.tsx │ │ │ ├── progress.tsx │ │ │ ├── radio-group.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── sheet.tsx │ │ │ ├── skeleton.tsx │ │ │ ├── skills.tsx │ │ │ ├── slider.tsx │ │ │ ├── sonner.tsx │ │ │ ├── stylized-image.tsx │ │ │ ├── switch.tsx │ │ │ ├── table.tsx │ │ │ ├── tabs.tsx │ │ │ ├── tag-list.tsx │ │ │ ├── textarea.tsx │ │ │ ├── toggle.tsx │ │ │ └── tooltip.tsx │ │ ├── website-for-sale-toast.tsx │ │ ├── wrapped-clerk-provider.tsx │ │ └── youtube-embed.tsx │ ├── config │ │ ├── data-table.ts │ │ ├── navigation.ts │ │ └── site.ts │ ├── data │ │ ├── blockchains.ts │ │ ├── categories.ts │ │ ├── gas-fees-calculator.ts │ │ ├── grants.ts │ │ └── use-cases.ts │ ├── hooks │ │ ├── use-config.ts │ │ ├── use-data-table.tsx │ │ ├── use-debounce.ts │ │ ├── use-lock-body.ts │ │ ├── use-mounted.ts │ │ ├── use-mutation-observer.ts │ │ ├── useBuffer.ts │ │ └── useUniqueJsonObjects.ts │ ├── lib │ │ ├── db.ts │ │ ├── filter-column.ts │ │ ├── fonts.ts │ │ ├── gas-fees-calculator.ts │ │ ├── seo.tsx │ │ ├── structured.tsx │ │ └── utils.ts │ ├── middleware.ts │ ├── models │ │ └── data-table.ts │ ├── pages │ │ └── api │ │ │ ├── hello.ts │ │ │ └── revalidate.tsx │ ├── registry │ │ ├── styles.ts │ │ └── themes.ts │ ├── schema.ts │ ├── styles │ │ └── globals.css │ ├── types │ │ ├── data-table.ts │ │ ├── db.ts │ │ ├── index.ts │ │ ├── nav.ts │ │ └── tabs.ts │ └── utils │ │ └── helpers.ts ├── static │ └── media │ │ ├── ogImag1.55b5e1ed.jpg │ │ ├── ogImage2.52ce9962.jpg │ │ └── profilePic.80cd2617.jpg ├── tailwind.config.ts └── tsconfig.json └── grant_intelligence ├── README.md ├── grant_intelligence ├── __init__.py ├── __pycache__ │ ├── clerk.cpython-312.pyc │ ├── common.cpython-312.pyc │ ├── db.cpython-312.pyc │ ├── models.cpython-312.pyc │ ├── models_clerk.cpython-312.pyc │ ├── models_db.cpython-312.pyc │ └── scraper.cpython-312.pyc ├── clerk.py ├── common.py ├── db.py ├── get_leads.py ├── migrate_data.py ├── models_clerk.py ├── models_db.py └── scraper.py ├── poetry.lock ├── pyproject.toml └── tests └── __init__.py /.cursor/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "datapilot": { 4 | "url": "http://localhost:7700/sse", 5 | "type": "sse" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | .vscode 39 | 40 | .env -------------------------------------------------------------------------------- /migrate/advent-calendar/advent-calendar/Card.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useState } from 'react' 2 | 3 | interface CardProps { 4 | index: number 5 | open: boolean 6 | setOpen: (bool: boolean) => void 7 | setActiveIndex: (index: number) => void 8 | } 9 | 10 | export const Card: FC = ({ index, open, setOpen, setActiveIndex }) => { 11 | const [warning, setWarning] = useState('') 12 | 13 | const onClick = () => { 14 | const day = new Date() 15 | if (index <= day.getDate()) { 16 | setActiveIndex(index) 17 | setOpen(!open) 18 | } else { 19 | setWarning('Not yet') 20 | } 21 | } 22 | return ( 23 |
27 |
28 |
{warning !== '' ? warning : index}
29 |
30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /migrate/advent-calendar/advent-calendar/Header.tsx: -------------------------------------------------------------------------------- 1 | export const Header = () => { 2 | return ( 3 |
4 |
5 |

6 | Crypto Jokes Advent Calendar 🎄 7 |

8 |

9 | SBF, Do Kwon and family made 2022 a shitty crypto bearish year, better joke about it 🤓 10 |

11 |
12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /migrate/advent-calendar/head.txt: -------------------------------------------------------------------------------- 1 | import { NextSeo } from 'next-seo' 2 | import type { NextSeoProps } from 'next-seo' 3 | import cover from '@/../public/advent-calendar/cover.png' 4 | 5 | import { NEXT_SEO_DEFAULT } from '@/../next-seo.config' // your path will vary 6 | 7 | export default async function Head() { 8 | const updateMeta: NextSeoProps = { 9 | ...NEXT_SEO_DEFAULT, 10 | title: 'NFT Advent Calendar 2022', 11 | openGraph: { 12 | title: 'Crypto Jokes NFT Advent Calendar 2022', 13 | description: 14 | 'SBF, Do Kwon and family made 2022 a shitty crypto bearish year, better joke about it 🤓', 15 | images: [ 16 | { 17 | url: cover!.src, 18 | width: cover!.width, 19 | height: cover!.height, 20 | alt: 'Crypto Jokes NFT Advent Calendar 2022', 21 | }, 22 | ], 23 | }, 24 | } 25 | return 26 | } 27 | -------------------------------------------------------------------------------- /migrate/advent-calendar/mint/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 |

7 | Mint one of the jokes as a memory! 8 |

9 |
10 | 17 |
18 | 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /migrate/advent-calendar/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useState } from 'react' 4 | import { Card } from '@components/advent-calendar/Card' 5 | import { Header } from '@components/advent-calendar/Header' 6 | import { Modal } from '@components/advent-calendar/Modal' 7 | 8 | export default function Home() { 9 | const [open, setOpen] = useState(false) 10 | const [activeIndex, setActiveIndex] = useState(0) 11 | const [jokes] = useState([ 12 | '', 13 | '', 14 | '', 15 | '', 16 | '', 17 | '', 18 | '', 19 | '', 20 | '', 21 | '', 22 | '', 23 | '', 24 | '', 25 | '', 26 | '', 27 | '', 28 | '', 29 | '', 30 | '', 31 | '', 32 | '', 33 | '', 34 | '', 35 | '', 36 | ]) 37 | 38 | return ( 39 | <> 40 |
41 |
42 |
43 | {jokes.map((joke, index) => { 44 | if (index < 24) { 45 | return ( 46 | 53 | ) 54 | } 55 | })} 56 |
57 |
58 | {/*
59 | 60 |
*/} 61 | 62 | 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /migrate/blog/[slug]/head.txt: -------------------------------------------------------------------------------- 1 | import { NextSeo } from 'next-seo' 2 | import type { NextSeoProps } from 'next-seo' 3 | import { NEXT_SEO_DEFAULT } from '@/../next-seo.config' // your path will vary 4 | import { strapi } from '@shared/strapi' 5 | import { headers } from 'next/headers' 6 | 7 | export default async function Head({ params: { slug } }: { params: { slug: string } }) { 8 | const { data: posts, meta } = await strapi.find('posts', { 9 | populate: 'deep', 10 | filters: { 11 | slug: { 12 | $eq: slug, 13 | }, 14 | }, 15 | }) 16 | 17 | const headerList = headers() 18 | const referer = headerList.get('referer') 19 | 20 | const [post] = posts 21 | const seo = post?.attributes?.seo 22 | const { openGraph } = seo 23 | 24 | // console.log({ post }) 25 | // console.log(openGraph?.images?.data) 26 | 27 | const updateMeta: NextSeoProps = { 28 | ...NEXT_SEO_DEFAULT, 29 | title: seo?.title, 30 | description: seo?.description, 31 | noindex: seo?.noIndex, 32 | nofollow: seo?.noFollow, 33 | openGraph: { 34 | title: openGraph?.title, 35 | description: openGraph?.description, 36 | url: referer || 'https://cryptoneur.xyz/blog/' + slug, 37 | images: openGraph?.images?.data?.map((image: any) => ({ 38 | url: image?.attributes?.url, 39 | width: image?.attributes?.width, 40 | height: image?.attributes?.height, 41 | alt: image?.attributes?.alternativeText, 42 | })), 43 | type: openGraph?.type, 44 | article: { 45 | publishedTime: post?.attributes?.createdAt, 46 | modifiedTime: post?.attributes?.updatedAt, 47 | authors: [post?.attributes?.authors?.data[0].attributes?.name], 48 | tags: post?.attributes?.tags?.data?.map((tag: any) => tag?.attributes?.name), 49 | }, 50 | }, 51 | } 52 | 53 | // console.log(updateMeta.openGraph) 54 | 55 | return 56 | } 57 | -------------------------------------------------------------------------------- /migrate/blog/head.txt: -------------------------------------------------------------------------------- 1 | import { NextSeo } from 'next-seo' 2 | import type { NextSeoProps } from 'next-seo' 3 | import { NEXT_SEO_DEFAULT } from '@/../next-seo.config' // your path will vary 4 | import { strapi } from '@shared/strapi' 5 | import { headers } from 'next/headers' 6 | 7 | export default async function Head({ params: { slug } }: { params: { slug: string } }) { 8 | const headerList = headers() 9 | const referer = headerList.get('referer') 10 | 11 | // console.log({ post }) 12 | // console.log(openGraph?.images?.data) 13 | 14 | const updateMeta: NextSeoProps = { 15 | ...NEXT_SEO_DEFAULT, 16 | title: 'Cryptoneur Blog', 17 | description: 18 | 'Welcome to my personal blog, where you can find in-depth tutorials and guides on the latest crypto and tech trends.', 19 | openGraph: { 20 | title: 'Cryptoneur Blog', 21 | description: 22 | 'Welcome to my personal blog, where you can find in-depth tutorials and guides on the latest crypto and tech trends.', 23 | url: referer || 'https://cryptoneur.xyz/blog/' + slug, 24 | type: 'website', 25 | }, 26 | } 27 | 28 | console.log({ updateMeta }) 29 | 30 | return 31 | } 32 | -------------------------------------------------------------------------------- /migrate/blog/layout.txt: -------------------------------------------------------------------------------- 1 | export const metadata = { 2 | title: 'Next.js', 3 | description: 'Generated by Next.js', 4 | } 5 | 6 | export default function RootLayout({ 7 | children, 8 | }: { 9 | children: React.ReactNode 10 | }) { 11 | return ( 12 | 13 | {children} 14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /migrate/blog/page.txt: -------------------------------------------------------------------------------- 1 | import BlogPostGrid from '@components/blog/BlogPostGrid' 2 | import { Header } from '@components/blog/Header' 3 | 4 | export default function Home() { 5 | return ( 6 |
7 |
8 | 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /migrate/playground/page.dep: -------------------------------------------------------------------------------- 1 | import { createBrowserClient } from '@utils/supabase-browser' 2 | 3 | const PlaygroundPage = async () => { 4 | const supabase = createBrowserClient() 5 | let query = supabase.from('grants').select('id,name,blockchains!inner(id)') 6 | 7 | query = query.in('blockchains.id', ['1']) 8 | query = query.limit(10) 9 | 10 | const { data, error } = await query 11 | 12 | return ( 13 | <> 14 |
{JSON.stringify(error, null, 2)}
15 |
{JSON.stringify(data, null, 2)}
16 | 17 | ) 18 | } 19 | 20 | export default PlaygroundPage 21 | -------------------------------------------------------------------------------- /migrate/prompt-playground/page.dep: -------------------------------------------------------------------------------- 1 | import { ApiKeyForm } from '@components/prompt-playground/ApiKeyForm' 2 | import { ApiKeyInput } from '@components/prompt-playground/ApiKeyInput' 3 | import { InputForm } from '@components/prompt-playground/InputForm' 4 | import { MatrixSelect } from '@components/prompt-playground/MatrixSelect' 5 | import { ToasterWrapper } from '@components/shared/ToasterWrapper' 6 | import { Form } from '@shared/Form' 7 | import { z } from 'zod' 8 | 9 | const PromptPlayground = () => { 10 | return ( 11 | <> 12 | 13 |
14 | {/* Title */} 15 |
16 |

17 | 18 | Enhanced 19 | {' '} 20 | Open AI Playground 21 |

22 |
23 | 24 |
25 | 26 | ) 27 | } 28 | 29 | export default PromptPlayground 30 | -------------------------------------------------------------------------------- /migrate/register/page.dep: -------------------------------------------------------------------------------- 1 | import { Auth } from '@components/auth/Auth' 2 | 3 | const RegisterPage = () => { 4 | return 5 | } 6 | 7 | export default RegisterPage 8 | -------------------------------------------------------------------------------- /migrate/sign-in/layout.tsx: -------------------------------------------------------------------------------- 1 | export const metadata = { 2 | title: 'Next.js', 3 | description: 'Generated by Next.js', 4 | } 5 | 6 | export default function RootLayout({ 7 | children, 8 | }: { 9 | children: React.ReactNode 10 | }) { 11 | return ( 12 | 13 | {children} 14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /migrate/sign-in/page.tsx: -------------------------------------------------------------------------------- 1 | import { Auth } from '@components/auth/Auth' 2 | 3 | const SignInPage = () => { 4 | return 5 | } 6 | 7 | export default SignInPage 8 | -------------------------------------------------------------------------------- /migrate/web3-grants/AuthAlert.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useSupabase } from '@components/supabase-provider' 4 | import { 5 | AlertDialog, 6 | AlertDialogAction, 7 | AlertDialogContent, 8 | AlertDialogDescription, 9 | AlertDialogFooter, 10 | AlertDialogHeader, 11 | AlertDialogTitle, 12 | } from '@components/ui/AlertDialog' 13 | import { FC, PropsWithChildren } from 'react' 14 | 15 | export interface AuthAlertProps extends PropsWithChildren { 16 | open: boolean 17 | } 18 | export const AuthAlert: FC = ({ children, open }) => { 19 | const { supabase, session } = useSupabase() 20 | 21 | return ( 22 | <> 23 | 24 | 25 | 26 | You are not logged in yet 27 | Please log in before creating a grant. 28 | 29 | 30 | Login 31 | 32 | 33 | 34 | 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /migrate/web3-grants/add/GrantFormTally.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { usePathname, useRouter } from 'next/navigation' 4 | import Script from 'next/script' 5 | import { FC } from 'react' 6 | 7 | export interface GrantFormTallyProps { 8 | grant?: any 9 | } 10 | export const GrantFormTally: FC = ({ grant }) => { 11 | const pathname = usePathname() 12 | const router = useRouter() 13 | 14 | // useEffect(() => { 15 | // if (pathname !== '/web3-grants/add') { 16 | // router.refresh() 17 | // } 18 | 19 | // }, []) 20 | 21 | // console.log({ pathname }) 22 | let tallyUrl = 23 | 'https://tally.so/embed/m6D0VN?alignLeft=1&hideTitle=1&transparentBackground=1&dynamicHeight=1' 24 | 25 | if (grant) { 26 | const filteredGrant = { 27 | ...Object.entries(grant) 28 | .filter(([key, value]) => value !== undefined && value !== null && value !== '') 29 | .reduce((result, [key, value]) => ({ ...result, [key]: value }), {}), 30 | } 31 | 32 | console.log({ ...filteredGrant }) 33 | tallyUrl = `${tallyUrl}&${new URLSearchParams({ 34 | edit: pathname === '/web3-grants/add' ? 'false' : 'true', 35 | ...filteredGrant, 36 | }).toString()}` 37 | } 38 | 39 | // console.log({ tallyUrl }) 40 | return ( 41 | <> 42 | 55 |
56 | 67 |
68 | 69 | ) 70 | } 71 | -------------------------------------------------------------------------------- /migrate/web3-grants/edit/ModalWrapper.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { FC, useState } from 'react' 4 | import { Modal } from './Modal' 5 | 6 | 7 | function 8 | 9 | export const ModalWrapper: FC = () => { 10 | const [open, setOpen] = useState(true) 11 | 12 | return ( 13 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /migrate/web3-grants/grant/NoInfo.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { ArrowRightCircleIcon } from '@heroicons/react/24/outline' 4 | import { usePathname } from 'next/navigation' 5 | import { FC } from 'react' 6 | 7 | export interface NoInfoProps {} 8 | export const NoInfo: FC = () => { 9 | const pathname = usePathname() 10 | 11 | console.log({ pathname }) 12 | 13 | return ( 14 | <> 15 | 19 |
20 | 21 | No info provided yet, contribute! 22 |
23 |
24 | 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /migrate/web3-grants/quote.tsx: -------------------------------------------------------------------------------- 1 | import { GraidentAvatar } from '@components/shared/GradientAvatar' 2 | import { FC } from 'react' 3 | 4 | export interface QuoteProps { 5 | quote: string 6 | person: string 7 | title?: string 8 | image: string 9 | } 10 | export const Quote: FC = ({ quote, person, title, image }) => { 11 | return ( 12 |
13 |
14 |
15 |
16 | 17 |
18 | 19 |
20 | 32 |
33 |
34 |

{quote}

35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 |
{person}
43 | {title &&
{title}
} 44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /migrate/web3-grants/search/DesktopFilterOption.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | import { FieldValues, UseFormRegister } from 'react-hook-form' 3 | 4 | export interface DesktopFilterOptionProps { 5 | option: any 6 | optionIdx: number 7 | section: any 8 | register: UseFormRegister 9 | key: string 10 | } 11 | export const DesktopFilterOption: FC = ({ 12 | option, 13 | section, 14 | optionIdx, 15 | register, 16 | key, 17 | }) => { 18 | // console.log({ option, optionIdx, section }) 19 | 20 | return ( 21 |
22 | 30 | 33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /migrate/web3-grants/search/Header.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | 3 | export const Header: FC = () => { 4 | return ( 5 |
6 |
7 |
8 |

Web3 Grants

9 |

10 | Up-to-date and complete collection of web3 grants. 11 |

12 |
13 | 14 | Add new Grant 15 | 16 |
17 |
18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /migrate/web3e-grants/(grant)/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | export const revalidate = 60 2 | 3 | import { GrantInfoCard } from '@components/web3-grants/grant/GrantInfoCard' 4 | import { GrantRfps } from '@components/web3-grants/grant/GrantRfps' 5 | import { Header } from '@components/web3-grants/grant/Header' 6 | import { createServerClient } from '@utils/supabase-server' 7 | import { Metadata, NextPage } from 'next' 8 | import { NextParsedUrlQuery } from 'next/dist/server/request-meta' 9 | 10 | interface Params { 11 | params: { 12 | slug: string 13 | } 14 | } 15 | 16 | export async function generateMetadata({ params }: Params): Promise { 17 | const supabase = createServerClient() 18 | 19 | const { data: grant, error: grantError } = await supabase 20 | .from('grants') 21 | .select('*') 22 | .eq('slug', params.slug) 23 | .maybeSingle() 24 | 25 | if (grantError || !grant) { 26 | return {} 27 | } 28 | 29 | return { 30 | title: `${grant.name} | Web3 Grants`, 31 | description: grant.description, 32 | openGraph: { 33 | title: grant.name, 34 | description: grant.description ? grant.description : '', 35 | images: [ 36 | { 37 | url: grant.logo, 38 | width: 800, 39 | height: 600, 40 | alt: grant.name, 41 | }, 42 | ], 43 | }, 44 | } 45 | } 46 | 47 | const Web3GrantPage = ({ params }: Params) => { 48 | const { slug } = params 49 | 50 | return ( 51 | <> 52 |
53 | {/* Page header */} 54 |
55 | 56 |
57 |
58 | {/* Description list*/} 59 | 60 | 65 | 70 |
71 |
72 |
73 | 74 | ) 75 | } 76 | 77 | export default Web3GrantPage 78 | -------------------------------------------------------------------------------- /migrate/web3e-grants/add/page.tsx: -------------------------------------------------------------------------------- 1 | import { GrantForm } from '@components/web3-grants/add/GrantForm' 2 | import { Modal } from '@components/web3-grants/edit/Modal' 3 | import { createServerClient } from '@utils/supabase-server' 4 | 5 | const AddGrant = async () => { 6 | const supabase = createServerClient() 7 | 8 | const { data: blockchains, error: blockchainsError } = await supabase 9 | .from('blockchains') 10 | .select('*') 11 | 12 | const { data: categories, error: categoriesError } = await supabase.from('categories').select('*') 13 | 14 | const { data: use_cases, error: useCasesError } = await supabase.from('use_cases').select('*') 15 | 16 | const { data: grant_blokchains, error: grantBlokchainsError } = await supabase 17 | .from('grant_blokchains') 18 | .select('*') 19 | 20 | const { data: grant_categories, error: grantCategoriesError } = await supabase 21 | .from('grant_categories') 22 | .select('*') 23 | 24 | const { data: grant_use_cases, error: grantUseCasesError } = await supabase 25 | .from('grant_use_cases') 26 | .select('*') 27 | 28 | const { data: fiats, error: fiatsError } = await supabase.from('fiats').select('*') 29 | 30 | // console.log({ blockchains, blockchainsError }) 31 | 32 | return ( 33 | <> 34 | 40 | 51 | 52 | ) 53 | } 54 | 55 | export default AddGrant 56 | -------------------------------------------------------------------------------- /migrate/web3e-grants/page.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next'; 2 | 3 | export const metadata: Metadata = { 4 | title: 'Web3 Grants', 5 | description: 6 | 'Find the perfect funding opportunity for your web3 project with our comprehensive and constantly updated grant database. Advanced filtering options and data-driven insights increase your chances of success. Join our growing community and contribute to the database.', 7 | keywords: 8 | 'web3, grants, funding, crypto, blockchain, ethereum, defi, dapp, dapps, web3 grants, grants', 9 | openGraph: { 10 | title: 'Web3 Grant Platform - Find Funding for Your Project', 11 | description: 12 | 'Find the perfect funding opportunity for your web3 project with our comprehensive and constantly updated grant database. Advanced filtering options and data-driven insights increase your chances of success. Join our growing community and contribute to the database.', 13 | url: 'https://cryptoneur.xyz/web3-grants', 14 | type: 'website', 15 | images: [ 16 | { 17 | url: `${process.env.NEXT_PUBLIC_URL}${image1.src}`, 18 | width: image1.width, 19 | height: image3.height, 20 | alt: 'Web3 Grant Platform - Find Funding for Your Project', 21 | }, 22 | { 23 | url: `${process.env.NEXT_PUBLIC_URL}${image2.src}`, 24 | width: image2.width, 25 | height: image2.height, 26 | alt: 'Web3 Grant Platform - Find Funding for Your Project', 27 | }, 28 | { 29 | url: `${process.env.NEXT_PUBLIC_URL}${image3.src}`, 30 | width: image3.width, 31 | height: image3.height, 32 | alt: 'Web3 Grant Platform - Find Funding for Your Project', 33 | }, 34 | ], 35 | }, 36 | }; 37 | 38 | export default function Web3Grants() { 39 | return ( 40 | <> 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/Author/_index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | import authors__felixVemmerMdx from './authors__felix-vemmer.mdx.json' assert { type: 'json' } 4 | 5 | export const allAuthors = [authors__felixVemmerMdx] 6 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/Page/_index.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/Page/_index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | 4 | 5 | export const allPages = [] 6 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/Post/_index.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/Post/_index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | 4 | 5 | export const allPosts = [] 6 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/index.d.ts: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | import { Post, Author, Page, DocumentTypes, DataExports } from './types' 4 | import { SourceProvideSchemaErrorJSON, SourceFetchDataErrorJSON } from 'contentlayer/core' 5 | 6 | export * from './types' 7 | 8 | export declare const allPosts: Post[] 9 | export declare const allAuthors: Author[] 10 | export declare const allPages: Page[] 11 | 12 | export declare const allDocuments: DocumentTypes[] 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/generated/index.mjs: -------------------------------------------------------------------------------- 1 | // NOTE This file is auto-generated by Contentlayer 2 | 3 | export { isType } from 'contentlayer/client' 4 | 5 | // NOTE During development Contentlayer imports from `.mjs` files to improve HMR speeds. 6 | // During (production) builds Contentlayer it imports from `.json` files to improve build performance. 7 | import allPosts from './Post/_index.json' assert { type: 'json' } 8 | import allAuthors from './Author/_index.json' assert { type: 'json' } 9 | import allPages from './Page/_index.json' assert { type: 'json' } 10 | 11 | export { allPosts, allAuthors, allPages } 12 | 13 | export const allDocuments = [...allPosts, ...allAuthors, ...allPages] 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/frontend/.contentlayer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dot-contentlayer", 3 | "description": "This package is auto-generated by Contentlayer", 4 | "version": "0.0.0-BAGCOISY", 5 | "exports": { 6 | "./generated": { 7 | "import": "./generated/index.mjs" 8 | } 9 | }, 10 | "typesVersions": { 11 | "*": { 12 | "generated": [ 13 | "./generated" 14 | ] 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .next 4 | build 5 | src/lib/database.types.ts 6 | package-lock.json 7 | pnpm-lock.yaml 8 | node_modules 9 | LICENSE 10 | 11 | out 12 | .next 13 | public 14 | drizzle 15 | directus-drizlle -------------------------------------------------------------------------------- /packages/frontend/.eslintrc-back.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "next/core-web-vitals", 8 | "plugin:@typescript-eslint/recommended", 9 | "prettier" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/explicit-module-boundary-types": "off", 13 | "@typescript-eslint/no-empty-interface": "off", 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/no-unused-vars": "off", 16 | "@typescript-eslint/no-non-null-assertion": "warn", 17 | "@typescript-eslint/no-empty-function": "warn", 18 | "react/no-children-prop": "warn", 19 | "react-hooks/exhaustive-deps": "off", 20 | "react/jsx-no-target-blank": "off", 21 | "no-extra-boolean-cast": "off", 22 | "prefer-const": "warn" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /packages/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | next-env.d.ts 15 | .next 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | .pnpm-debug.log* 29 | 30 | # local env files 31 | .env*.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | 39 | webpack 40 | 41 | # Sitemap file 42 | sitemap.xml 43 | sitemap-0.xml 44 | 45 | # Robots.txt 46 | robots.txt 47 | 48 | Makefile 49 | 50 | bun.lockb 51 | 52 | -------------------------------------------------------------------------------- /packages/frontend/.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers = true 2 | -------------------------------------------------------------------------------- /packages/frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .next 4 | build 5 | src/lib/database.types.ts 6 | package-lock.json 7 | pnpm-lock.yaml 8 | node_modules 9 | LICENSE 10 | 11 | out 12 | .next 13 | public 14 | drizzle 15 | directus-drizlle -------------------------------------------------------------------------------- /packages/frontend/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | -------------------------------------------------------------------------------- /packages/frontend/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/frontend/content/authors/felix-vemmer.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Felix Vemmer 3 | avatar: /logos/felix-vemmer.png 4 | twitter: felixvemmer 5 | --- 6 | -------------------------------------------------------------------------------- /packages/frontend/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv' 2 | import type { Config } from 'drizzle-kit' 3 | 4 | config({ 5 | path: './.env.local', 6 | }) 7 | 8 | const connectionString = process.env.DATABASE_URL 9 | 10 | if (!connectionString) { 11 | throw new Error('DATABASE_URL environment variable not found') 12 | } 13 | 14 | export default { 15 | schema: './src/schema.ts', 16 | out: './drizzle', 17 | dbCredentials: { 18 | connectionString, 19 | }, 20 | driver: 'pg', 21 | } satisfies Config 22 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0000_nifty_mephistopheles.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "organizations" ( 2 | "id" text PRIMARY KEY NOT NULL, 3 | "name" varchar(256) NOT NULL, 4 | "slug" varchar(256) NOT NULL, 5 | "image_url" varchar(256) NOT NULL, 6 | "has_image" boolean NOT NULL, 7 | "created_by" text NOT NULL, 8 | "created_at" timestamp NOT NULL, 9 | "updated_at" timestamp NOT NULL, 10 | "public_metadata" jsonb, 11 | "private_metadata" jsonb, 12 | "max_allowed_memberships" integer NOT NULL, 13 | "admin_delete_enabled" boolean NOT NULL, 14 | "members_count" integer 15 | ); 16 | --> statement-breakpoint 17 | CREATE TABLE IF NOT EXISTS "users" ( 18 | "id" text PRIMARY KEY NOT NULL, 19 | "username" text, 20 | "first_name" text, 21 | "last_name" text, 22 | "image_url" text NOT NULL, 23 | "has_image" boolean DEFAULT false NOT NULL, 24 | "primary_email_address" text, 25 | "primary_phone_number" text, 26 | "public_metadata" jsonb, 27 | "private_metadata" jsonb, 28 | "unsafe_metadata" jsonb, 29 | "last_sign_in_at" date, 30 | "created_at" date, 31 | "updated_at" date NOT NULL 32 | ); 33 | --> statement-breakpoint 34 | CREATE INDEX IF NOT EXISTS "created_by_idx" ON "organizations" ("created_by");--> statement-breakpoint 35 | CREATE INDEX IF NOT EXISTS "name_idx" ON "organizations" ("name");--> statement-breakpoint 36 | CREATE INDEX IF NOT EXISTS "slug_idx" ON "organizations" ("slug");--> statement-breakpoint 37 | CREATE INDEX IF NOT EXISTS "username_idx" ON "users" ("username");--> statement-breakpoint 38 | CREATE INDEX IF NOT EXISTS "primary_email_address_idx" ON "users" ("primary_email_address");--> statement-breakpoint 39 | CREATE INDEX IF NOT EXISTS "primary_phone_number_idx" ON "users" ("primary_phone_number");--> statement-breakpoint 40 | DO $$ BEGIN 41 | ALTER TABLE "organizations" ADD CONSTRAINT "organizations_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action; 42 | EXCEPTION 43 | WHEN duplicate_object THEN null; 44 | END $$; 45 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0002_sharp_kate_bishop.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "currencies" ( 2 | "id" text PRIMARY KEY DEFAULT 'cur_' || nanoid() NOT NULL, 3 | "name" varchar(256) NOT NULL, 4 | "symbol" varchar(256) NOT NULL, 5 | "sign" varchar(256) NOT NULL, 6 | "created_at" timestamp DEFAULT now() NOT NULL, 7 | "updated_at" timestamp DEFAULT now() NOT NULL 8 | ); 9 | --> statement-breakpoint 10 | DROP INDEX IF EXISTS "created_by_idx";--> statement-breakpoint 11 | DROP INDEX IF EXISTS "name_idx";--> statement-breakpoint 12 | DROP INDEX IF EXISTS "slug_idx";--> statement-breakpoint 13 | CREATE INDEX IF NOT EXISTS "currencies_name_idx" ON "currencies" ("name");--> statement-breakpoint 14 | CREATE INDEX IF NOT EXISTS "currencies_symbol_idx" ON "currencies" ("symbol");--> statement-breakpoint 15 | CREATE INDEX IF NOT EXISTS "organizations_created_by_idx" ON "organizations" ("created_by");--> statement-breakpoint 16 | CREATE INDEX IF NOT EXISTS "organizations_name_idx" ON "organizations" ("name");--> statement-breakpoint 17 | CREATE INDEX IF NOT EXISTS "organizations_slug_idx" ON "organizations" ("slug"); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0004_odd_thor.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "transaction_types" ( 2 | "id" text PRIMARY KEY DEFAULT 'txn_type_' || nanoid() NOT NULL, 3 | "name" varchar(256) NOT NULL, 4 | "gas" integer NOT NULL, 5 | "is_published" boolean DEFAULT false NOT NULL, 6 | "created_at" timestamp DEFAULT now() NOT NULL, 7 | "updated_at" timestamp DEFAULT now() NOT NULL 8 | ); 9 | --> statement-breakpoint 10 | CREATE INDEX IF NOT EXISTS "transaction_types_name_idx" ON "transaction_types" ("name"); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0005_early_maverick.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO 2 | transaction_types (name, gas) 3 | VALUES 4 | ('Convex Finance: Stake', 514772), 5 | ('Lido: Stake', 82685), 6 | ('Yearn Finance: Deposit', 216306), 7 | ('Standard Transfer', 21000), 8 | ('ERC20: Transfer', 65000), 9 | ('ERC721: Transfer', 84904), 10 | ('USDT: Transfer', 54128), 11 | ('OpenSea: Sale', 71645), 12 | ('SuperRare: Sale', 130704), 13 | ('Rarible: Sale', 245730), 14 | ('LooksRare: Sale', 326897), 15 | ('SuperRare: Offer', 85191), 16 | ('Uniswap V3: Swap', 184523), 17 | ('SushiSwap: Swap', 141225), 18 | ('Curve: Swap', 183758), 19 | ('Balancer: Swap', 196625), 20 | ('Bancor: Swap', 183193), 21 | ('1inch: Swap', 141905), 22 | ('KyberSwap: Swap', 144389), 23 | ('Uniswap V2: Swap', 152809), 24 | ('CoW Protocol: Swap', 343353), 25 | ('Uniswap V3: Add Liquidity', 216912), 26 | ('Curve: Add Liquidity', 271909), 27 | ('ENS: Register Domain', 266996), 28 | ('Arbitrum: Deposit', 91101), 29 | ('Optimism: Deposit', 150829), 30 | ('Polygon: Deposit', 149208), 31 | ('Ronin: Deposit', 163754), 32 | ('zkSync: Deposit', 143430), 33 | ('Beacon Chain: Deposit', 52933), 34 | ('Ribbon Finance: Deposit', 93014), 35 | ('Ribbon Finance: Withdraw', 98895), 36 | ('dYdX: Borrow', 174271), 37 | ('MakerDAO: Borrow', 233329), 38 | ('Compound: Collect', 1239371), 39 | ('Compound: Borrow', 340168), 40 | ('Compound: Repay', 112338), 41 | ('KyberSwap: Stake', 214835), 42 | ('Tornado.Cash: Deposit', 1014025), 43 | ('Tornado.Cash: Withdraw', 360831), 44 | ('0x: Swap', 327259), 45 | ('Aave: Borrow', 318788), 46 | ('Aave: Repay', 199772), 47 | ('Hop Protocol: Bridge', 121565), 48 | ('Multichain: Bridge', 57887), 49 | ('Across Protocol: Bridge', 120965), 50 | ('Synapse: Bridge', 107905), 51 | ('Lido: Stake', 87614), 52 | ('Gem: Batch Buy', 340926), 53 | ('L2: Deposits', 250000), 54 | ('Gnosis Safe: Creation with 2 Owners', 307126), 55 | ('Gnosis Safe: Creation with 3 Owners', 331341), 56 | ('Gnosis Safe: Creation with 4 Owners', 355556); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0006_deep_harpoon.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "blockchains" ( 2 | "id" text PRIMARY KEY DEFAULT 'bc_' || nanoid() NOT NULL, 3 | "name" varchar(256) NOT NULL, 4 | "old_id" text, 5 | "created_at" timestamp DEFAULT now() NOT NULL, 6 | "updated_at" timestamp DEFAULT now() NOT NULL 7 | ); 8 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0007_friendly_cannonball.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" DROP COLUMN IF EXISTS "old_id"; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0008_first_luminals.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" ADD COLUMN "old_id" integer; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0009_clammy_jane_foster.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" DROP COLUMN IF EXISTS "old_id"; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0010_absent_james_howlett.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" ALTER COLUMN "name" SET DATA TYPE text;--> statement-breakpoint 2 | ALTER TABLE "blockchains" ADD COLUMN "slug" text NOT NULL; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0011_watery_wildside.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" ADD CONSTRAINT "blockchains_slug_unique" UNIQUE("slug"); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0012_fast_sir_ram.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "blockchains" ADD COLUMN "old_id" integer NOT NULL;--> statement-breakpoint 2 | ALTER TABLE "blockchains" ADD CONSTRAINT "blockchains_old_id_unique" UNIQUE("old_id"); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0013_breezy_taskmaster.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "fiat_currencies" ( 2 | "id" text PRIMARY KEY DEFAULT 'fiat_' || nanoid() NOT NULL, 3 | "old_id" integer NOT NULL, 4 | "name" text NOT NULL, 5 | "symbol" text NOT NULL, 6 | "sign" text NOT NULL, 7 | "created_at" timestamp DEFAULT now() NOT NULL, 8 | "updated_at" timestamp DEFAULT now() NOT NULL, 9 | CONSTRAINT "fiat_currencies_old_id_unique" UNIQUE("old_id") 10 | ); 11 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0014_nebulous_klaw.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "categories" ( 2 | "id" text PRIMARY KEY DEFAULT 'cat_' || nanoid() NOT NULL, 3 | "name" text NOT NULL, 4 | "slug" text NOT NULL, 5 | "created_at" timestamp DEFAULT now() NOT NULL, 6 | "updated_at" timestamp DEFAULT now() NOT NULL, 7 | CONSTRAINT "categories_slug_unique" UNIQUE("slug") 8 | ); 9 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0015_bizarre_lord_hawal.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "categories" ADD COLUMN "old_id" integer NOT NULL;--> statement-breakpoint 2 | ALTER TABLE "categories" ADD CONSTRAINT "categories_old_id_unique" UNIQUE("old_id"); -------------------------------------------------------------------------------- /packages/frontend/drizzle/0016_vengeful_medusa.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "use_cases" ( 2 | "id" text PRIMARY KEY DEFAULT 'use_case_' || nanoid() NOT NULL, 3 | "old_id" integer NOT NULL, 4 | "name" text NOT NULL, 5 | "slug" text NOT NULL, 6 | "created_at" timestamp DEFAULT now() NOT NULL, 7 | "updated_at" timestamp DEFAULT now() NOT NULL, 8 | CONSTRAINT "use_cases_old_id_unique" UNIQUE("old_id"), 9 | CONSTRAINT "use_cases_slug_unique" UNIQUE("slug") 10 | ); 11 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0017_jittery_weapon_omega.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "grants" ( 2 | "id" text PRIMARY KEY DEFAULT 'gr' || nanoid() NOT NULL, 3 | "old_id" integer NOT NULL, 4 | "name" text NOT NULL, 5 | "description" text NOT NULL, 6 | "active" boolean DEFAULT true NOT NULL, 7 | "url_application" text NOT NULL, 8 | "url_info" text NOT NULL, 9 | "content" text, 10 | "slug" text NOT NULL, 11 | "funding_amount_min" integer NOT NULL, 12 | "funding_amount_max" integer NOT NULL, 13 | "funding_amount_currency" text NOT NULL, 14 | "github_url" text, 15 | "twitter_url" text, 16 | "discord_url" text, 17 | "website_url" text, 18 | "logo_url" text, 19 | "created_at" timestamp DEFAULT now() NOT NULL, 20 | "updated_at" timestamp DEFAULT now() NOT NULL, 21 | CONSTRAINT "grants_old_id_unique" UNIQUE("old_id"), 22 | CONSTRAINT "grants_slug_unique" UNIQUE("slug") 23 | ); 24 | --> statement-breakpoint 25 | ALTER TABLE "use_cases" ALTER COLUMN "id" SET DEFAULT 'uc' || nanoid();--> statement-breakpoint 26 | CREATE INDEX IF NOT EXISTS "grants_name_idx" ON "grants" ("name");--> statement-breakpoint 27 | DO $$ BEGIN 28 | ALTER TABLE "grants" ADD CONSTRAINT "grants_funding_amount_currency_currencies_id_fk" FOREIGN KEY ("funding_amount_currency") REFERENCES "currencies"("id") ON DELETE no action ON UPDATE no action; 29 | EXCEPTION 30 | WHEN duplicate_object THEN null; 31 | END $$; 32 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0018_real_magma.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "grants" DROP CONSTRAINT "grants_funding_amount_currency_currencies_id_fk"; 2 | --> statement-breakpoint 3 | DO $$ BEGIN 4 | ALTER TABLE "grants" ADD CONSTRAINT "grants_funding_amount_currency_fiat_currencies_id_fk" FOREIGN KEY ("funding_amount_currency") REFERENCES "fiat_currencies"("id") ON DELETE no action ON UPDATE no action; 5 | EXCEPTION 6 | WHEN duplicate_object THEN null; 7 | END $$; 8 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0019_exotic_norrin_radd.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "grants" ALTER COLUMN "funding_amount_min" DROP NOT NULL;--> statement-breakpoint 2 | ALTER TABLE "grants" ALTER COLUMN "funding_amount_max" DROP NOT NULL;--> statement-breakpoint 3 | ALTER TABLE "grants" ALTER COLUMN "funding_amount_currency" DROP NOT NULL; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0020_robust_vision.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "grants" ADD COLUMN "organization_id" text;--> statement-breakpoint 2 | DO $$ BEGIN 3 | ALTER TABLE "grants" ADD CONSTRAINT "grants_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE no action ON UPDATE no action; 4 | EXCEPTION 5 | WHEN duplicate_object THEN null; 6 | END $$; 7 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0021_adorable_spencer_smythe.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "grant_blockchains" ( 2 | "id" text PRIMARY KEY DEFAULT 'gbc_' || nanoid() NOT NULL, 3 | "grant_id" text, 4 | "blockchain_id" text 5 | ); 6 | --> statement-breakpoint 7 | DO $$ BEGIN 8 | ALTER TABLE "grant_blockchains" ADD CONSTRAINT "grant_blockchains_grant_id_grants_id_fk" FOREIGN KEY ("grant_id") REFERENCES "grants"("id") ON DELETE no action ON UPDATE no action; 9 | EXCEPTION 10 | WHEN duplicate_object THEN null; 11 | END $$; 12 | --> statement-breakpoint 13 | DO $$ BEGIN 14 | ALTER TABLE "grant_blockchains" ADD CONSTRAINT "grant_blockchains_blockchain_id_blockchains_id_fk" FOREIGN KEY ("blockchain_id") REFERENCES "blockchains"("id") ON DELETE no action ON UPDATE no action; 15 | EXCEPTION 16 | WHEN duplicate_object THEN null; 17 | END $$; 18 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0022_bouncy_annihilus.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "grant_blockchains" ADD COLUMN "created_at" timestamp DEFAULT now() NOT NULL;--> statement-breakpoint 2 | ALTER TABLE "grant_blockchains" ADD COLUMN "updated_at" timestamp DEFAULT now() NOT NULL; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0023_nappy_the_hood.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "grant_categories" ( 2 | "id" text PRIMARY KEY DEFAULT 'gcat_' || nanoid() NOT NULL, 3 | "grant_id" text, 4 | "category_id" text, 5 | "created_at" timestamp DEFAULT now() NOT NULL, 6 | "updated_at" timestamp DEFAULT now() NOT NULL 7 | ); 8 | --> statement-breakpoint 9 | DO $$ BEGIN 10 | ALTER TABLE "grant_categories" ADD CONSTRAINT "grant_categories_grant_id_grants_id_fk" FOREIGN KEY ("grant_id") REFERENCES "grants"("id") ON DELETE no action ON UPDATE no action; 11 | EXCEPTION 12 | WHEN duplicate_object THEN null; 13 | END $$; 14 | --> statement-breakpoint 15 | DO $$ BEGIN 16 | ALTER TABLE "grant_categories" ADD CONSTRAINT "grant_categories_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "categories"("id") ON DELETE no action ON UPDATE no action; 17 | EXCEPTION 18 | WHEN duplicate_object THEN null; 19 | END $$; 20 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0024_first_king_cobra.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "grant_use_cases" ( 2 | "id" text PRIMARY KEY DEFAULT 'guc_' || nanoid() NOT NULL, 3 | "grant_id" text, 4 | "use_case_id" text, 5 | "created_at" timestamp DEFAULT now() NOT NULL, 6 | "updated_at" timestamp DEFAULT now() NOT NULL 7 | ); 8 | --> statement-breakpoint 9 | DO $$ BEGIN 10 | ALTER TABLE "grant_use_cases" ADD CONSTRAINT "grant_use_cases_grant_id_grants_id_fk" FOREIGN KEY ("grant_id") REFERENCES "grants"("id") ON DELETE no action ON UPDATE no action; 11 | EXCEPTION 12 | WHEN duplicate_object THEN null; 13 | END $$; 14 | --> statement-breakpoint 15 | DO $$ BEGIN 16 | ALTER TABLE "grant_use_cases" ADD CONSTRAINT "grant_use_cases_use_case_id_use_cases_id_fk" FOREIGN KEY ("use_case_id") REFERENCES "use_cases"("id") ON DELETE no action ON UPDATE no action; 17 | EXCEPTION 18 | WHEN duplicate_object THEN null; 19 | END $$; 20 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0025_fancy_gideon.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS "test_table" ( 2 | "id" text PRIMARY KEY NOT NULL, 3 | "name" text 4 | ); 5 | -------------------------------------------------------------------------------- /packages/frontend/drizzle/0026_concerned_the_hunter.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "test_table" RENAME COLUMN "name" TO "name_test"; -------------------------------------------------------------------------------- /packages/frontend/drizzle/0027_volatile_dracula.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE "test_table"; -------------------------------------------------------------------------------- /packages/frontend/i18n.ts: -------------------------------------------------------------------------------- 1 | import { getRequestConfig } from 'next-intl/server' 2 | import { notFound } from 'next/navigation' 3 | 4 | export default getRequestConfig(async ({ locale }) => { 5 | if (!locales.includes(locale as any)) notFound() 6 | 7 | return { 8 | messages: (await import(`./messages/${locale}.json`)).default, 9 | timeZone: 'Europe/Berlin', 10 | now: new Date(), 11 | formats: { 12 | dateTime: { 13 | short: { 14 | day: 'numeric', 15 | month: 'short', 16 | year: 'numeric', 17 | }, 18 | }, 19 | number: { 20 | precise: { 21 | maximumFractionDigits: 5, 22 | }, 23 | }, 24 | list: { 25 | enumeration: { 26 | style: 'long', 27 | type: 'conjunction', 28 | }, 29 | }, 30 | }, 31 | } 32 | }) 33 | 34 | export const locales = ['en', 'de'] 35 | -------------------------------------------------------------------------------- /packages/frontend/messages/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "site": { 3 | "description": "Felix Vemmers Blog: Ihr Zugang zu Python, TypeScript, Full-Stack-Meisterschaft. Abonnieren Sie für exklusiven Inhalt und werden Sie Teil unserer Lerngemeinschaft!" 4 | }, 5 | "blog": { 6 | "title": "Das Neueste von meinem Blog", 7 | "subtitle": "Klare Einblicke und praktische Ratschläge zu Python, TypeScript und allem, was mit Full-Stack zu tun hat.", 8 | "tocHeading": "Auf dieser Seite" 9 | }, 10 | "index": { 11 | "notFound": "Seite nicht gefunden", 12 | "hero": { 13 | "title": "👋 Willkommen auf meiner persönlichen Webseite", 14 | "description": "Hey, ich bin Felix, Full-Stack-Entwickler und Indiepreneur aus Berlin. Hier findest du klare Einblicke und praktische Ratschläge zu Python, TypeScript und allem, was mit Full-Stack zu tun hat.", 15 | "primaryCTA": "Beratungsdienste", 16 | "secondaryCTA": "Lese meinen Blog" 17 | }, 18 | "skills": { 19 | "section": "Fähigkeiten", 20 | "title": "Womit kann ich dir helfen?", 21 | "description": "Ich bin ein self-taught Developer mit einem CEMS Master in internationalem Management. Dank meiner Kombination aus Geschäftssinn und technischem Verständnis kann ich nicht nur komplexe technische Ideen verständlich vermitteln, sondern diese auch erfolgreich umsetzen." 22 | }, 23 | "testimonials": { 24 | "title": "Was Kunden und Leser sagen", 25 | "section": "Referenzen" 26 | }, 27 | "bookAMeeeting": { 28 | "title": "Interessiert an einer Zusammenarbeit?", 29 | "section": "Meeting Buchen" 30 | }, 31 | "blog": { 32 | "title": "Das Neueste von meinem Blog", 33 | "section": "Blog" 34 | } 35 | }, 36 | "components": { 37 | "skills": { 38 | "tools": "Tools / Frameworks", 39 | "languages": "Expertise", 40 | "fullstack": { 41 | "description": "Ich verwandle deine individuellen Ideen in moderne Web-Anwendungen." 42 | }, 43 | "dataAndAI": { 44 | "description": "Ich biete dir Einblicke und helfe dir dabei, skalierbare Datenprodukte und AI Services zu erstellen. " 45 | }, 46 | "businessAndMarketing": { 47 | "description": "Lerne wie du dein aktuelles Geschäft optimieren kannst oder erhalte Feedback zu einer völlig neuen Geschäftsidee." 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/frontend/migrate.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv' 2 | import { drizzle } from 'drizzle-orm/postgres-js' 3 | import { migrate } from 'drizzle-orm/postgres-js/migrator' 4 | import postgres from 'postgres' 5 | 6 | config({ 7 | path: './.env.local', 8 | }) 9 | 10 | const connectionString = process.env.DATABASE_URL 11 | 12 | if (!connectionString) { 13 | throw new Error('DATABASE_URL is not defined') 14 | } 15 | 16 | const sql = postgres(connectionString, { max: 1 }) 17 | const db = drizzle(sql) 18 | 19 | ;(async () => { 20 | try { 21 | await migrate(db, { migrationsFolder: 'drizzle' }) 22 | } finally { 23 | await sql.end() 24 | } 25 | })() 26 | -------------------------------------------------------------------------------- /packages/frontend/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | const withNextIntl = require('next-intl/plugin')( 3 | // This is the default (also the `src` folder is supported out of the box) 4 | './i18n.ts', 5 | ) 6 | 7 | /** @type {import('next').NextConfig} */ 8 | const nextConfig = { 9 | experimental: { 10 | ppr: false, 11 | }, 12 | eslint: { 13 | // Disabling ESLint during production builds 14 | ignoreDuringBuilds: true, 15 | }, 16 | images: { 17 | remotePatterns: [ 18 | { 19 | protocol: 'https', 20 | hostname: '**', 21 | }, 22 | { 23 | protocol: 'http', 24 | hostname: '**', 25 | }, 26 | ], 27 | dangerouslyAllowSVG: true, 28 | }, 29 | async rewrites() { 30 | return [ 31 | { 32 | source: '/ingest/:path*', 33 | destination: 'https://eu.posthog.com/:path*', 34 | }, 35 | ] 36 | }, 37 | } 38 | 39 | module.exports = withNextIntl(withContentlayer(nextConfig)) 40 | -------------------------------------------------------------------------------- /packages/frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | plugins: { 4 | tailwindcss: {}, 5 | autoprefixer: {}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /packages/frontend/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | printWidth: 100, 6 | tabWidth: 2, 7 | useTabs: false, 8 | plugins: [ 9 | '@trivago/prettier-plugin-sort-imports', 10 | 'prettier-plugin-tailwindcss', 11 | 'prettier-plugin-organize-imports', 12 | ], 13 | importOrder: [ 14 | '^((react|next)/(.*)$)|^((react|next)$)', 15 | '', 16 | '^@(config|types|styles|utils|hooks|components|app|pages|features)/(.*)$', 17 | '^[./]', 18 | ], 19 | importOrderSeparation: true, 20 | overrides: [ 21 | { 22 | files: ['*.ts', '*.tsx'], 23 | options: { 24 | parser: 'typescript', 25 | importOrderParserPlugins: ['typescript', 'jsx'], 26 | }, 27 | }, 28 | ], 29 | } 30 | -------------------------------------------------------------------------------- /packages/frontend/public/VitalikButerin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/VitalikButerin.jpg -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/cover.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik1.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik10.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik11.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik12.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik13.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik14.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik15.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik16.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik17.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik18.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik19.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik2.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik20.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik21.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik22.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik23.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik24.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik3.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik4.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik5.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik6.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik7.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik8.png -------------------------------------------------------------------------------- /packages/frontend/public/advent-calendar/vitalik9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/advent-calendar/vitalik9.png -------------------------------------------------------------------------------- /packages/frontend/public/alarm-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/favicon.ico -------------------------------------------------------------------------------- /packages/frontend/public/gas-fees-calculator/ogImag1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/gas-fees-calculator/ogImag1.jpg -------------------------------------------------------------------------------- /packages/frontend/public/gas-fees-calculator/ogImage2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/gas-fees-calculator/ogImage2.jpg -------------------------------------------------------------------------------- /packages/frontend/public/logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logo_transparent.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/bertelsmann-stiftung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/bertelsmann-stiftung.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/cryptoticker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/cryptoticker.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/deutsche-bank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/deutsche-bank.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/lectura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/lectura.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/monitor-deloitte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/monitor-deloitte.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/n26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/n26.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/priceloop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/priceloop.png -------------------------------------------------------------------------------- /packages/frontend/public/logos/zapper-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/logos/zapper-logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/arbitrum_one_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/arbitrum_one_logo.jpeg -------------------------------------------------------------------------------- /packages/frontend/public/networks/avalanche_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/avalanche_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/avalanche_logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/avalanche_logo.webp -------------------------------------------------------------------------------- /packages/frontend/public/networks/binance_smart_chain_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/binance_smart_chain_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/celo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/celo_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/ethereum_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/ethereum_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/fantom_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/fantom_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/gnosis_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/gnosis_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/harmony_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/harmony_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/loopring_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/loopring_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/moonriver_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/moonriver_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/optimism_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/optimism_logo.jpeg -------------------------------------------------------------------------------- /packages/frontend/public/networks/optimism_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/optimism_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/polygon_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/polygon_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/networks/zksync_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/zksync_logo.jpeg -------------------------------------------------------------------------------- /packages/frontend/public/networks/zksync_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/networks/zksync_logo.png -------------------------------------------------------------------------------- /packages/frontend/public/og/web-3-grants/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/og/web-3-grants/image1.jpg -------------------------------------------------------------------------------- /packages/frontend/public/og/web-3-grants/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/og/web-3-grants/image2.jpg -------------------------------------------------------------------------------- /packages/frontend/public/og/web-3-grants/image3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/og/web-3-grants/image3.jpg -------------------------------------------------------------------------------- /packages/frontend/public/personal-projects/backlinkgpt-com.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/personal-projects/backlinkgpt-com.png -------------------------------------------------------------------------------- /packages/frontend/public/personal-projects/felixvemmer-com.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/personal-projects/felixvemmer-com.png -------------------------------------------------------------------------------- /packages/frontend/public/personal-projects/nocode-scraper-com.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/personal-projects/nocode-scraper-com.png -------------------------------------------------------------------------------- /packages/frontend/public/profilePic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/profilePic.jpg -------------------------------------------------------------------------------- /packages/frontend/public/quotes/AwWgWl-Y_400x400.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/public/quotes/AwWgWl-Y_400x400.jpg -------------------------------------------------------------------------------- /packages/frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/(landing)/sign-in/[[...sign-in]]/page.tsx: -------------------------------------------------------------------------------- 1 | import { SignIn } from '@clerk/nextjs' 2 | 3 | export default function Page() { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/(landing)/sign-up/[[...sign-up]]/page.tsx: -------------------------------------------------------------------------------- 1 | import { SignUp } from '@clerk/nextjs' 2 | 3 | export default function Page() { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/about/page.tsx: -------------------------------------------------------------------------------- 1 | import { Featured } from '@/components/featured' 2 | import { PageHeader, PageHeaderDescription, PageHeaderHeading } from '@/components/page-header' 3 | import Image from 'next/image' 4 | 5 | export default function AboutPage() { 6 | return ( 7 | <> 8 |
9 | 10 | Felix Vemmer 18 | 19 | 20 | {'👋 Welcome to cryptoneur.xyz'} 21 | 22 | 23 | { 24 | 'I am building the largest crypto-currency resource base for entrpreneurs in web3. Feel free to check out my other projects in the meantime.' 25 | } 26 | 27 | 28 |
29 | 30 | 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/page.tsx: -------------------------------------------------------------------------------- 1 | import { PageHeader, PageHeaderDescription, PageHeaderHeading } from '@/components/page-header' 2 | import { buttonVariants } from '@/components/ui/button' 3 | import { cn } from '@/lib/utils' 4 | import Link from 'next/link' 5 | 6 | export default function IndexPage() { 7 | return ( 8 |
9 | 10 | {/* 14 | 🎉 {' '} 15 | Test test. 16 | Introducing Style, a new CLI and more. 17 | 18 | */} 19 | 20 | {/* Felix Vemmer */} 28 | 29 | 30 | The Best Resources for Web3 Entrepreneurs 31 | 32 | 33 | Discover the ultimate collection of resources tailored for the ambitious Web3 34 | entrepreneur. Dive into a world where innovation meets opportunity. 35 | 36 |
37 | 47 | Gas Fees Caculator 48 | 49 | 53 | Web3 Grants 54 | 55 |
56 |
57 | {/* KPIs */} 58 | {/* }> 59 | 60 | */} 61 |
62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/web3-grants/grants/page.tsx: -------------------------------------------------------------------------------- 1 | import { GrantsTable } from '@/components/tables/grants' 2 | import { SGetGrantsParams, TGetGrantsParams, getGrants } from '@/data/grants' 3 | 4 | export default async function GrantsTablePage({ 5 | searchParams, 6 | }: { 7 | searchParams: TGetGrantsParams 8 | }) { 9 | const parsedSearchParams = SGetGrantsParams.parse(searchParams) 10 | 11 | const grantsTableData = getGrants(parsedSearchParams) 12 | 13 | return ( 14 | <> 15 | {/*
{JSON.stringify(parsedSearchParams, null, 2)}
*/} 16 | 17 | 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/web3-grants/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function GrantsLayoutPage({ children }: { children: React.ReactNode }) { 2 | return ( 3 | <> 4 |
{children}
5 | 6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /packages/frontend/src/app/[locale]/web3-grants/page.tsx: -------------------------------------------------------------------------------- 1 | import { Features } from '@/components/features' 2 | import { FoundersNote } from '@/components/founders-note' 3 | import { 4 | PageActions, 5 | PageHeader, 6 | PageHeaderDescription, 7 | PageHeaderHeading, 8 | } from '@/components/page-header' 9 | import { 10 | Accordion, 11 | AccordionContent, 12 | AccordionItem, 13 | AccordionTrigger, 14 | } from '@/components/ui/accordion' 15 | import { buttonVariants } from '@/components/ui/button' 16 | import { getGrantsCount } from '@/data/grants' 17 | import { cn } from '@/lib/utils' 18 | import Link from 'next/link' 19 | 20 | export default async function Web3GrantsPage() { 21 | const grantsCount = await getGrantsCount() 22 | 23 | return ( 24 |
25 | 26 | {/* */} 27 | Crunchbase for Web3 Grants 28 | 29 | {`We have a complete and up-to-date database of ${grantsCount} web3 grants. Filter and search for grants by category, amount, and more.`} 30 | 31 | 32 | 40 | Explore Grants 41 | 42 | 43 | 44 | 45 | 46 | {/* FAQ */} 47 | 48 | 49 | FAQ 50 | 51 | 57 | 58 | What is your web3 grant platform about? 59 | 60 | Our web3 grant platform is a database of web3 grants. It's a place where you can find 61 | information about web3 grants. Start 62 | 63 | exploring 64 | 65 | to see the grants. 66 | 67 | 68 | 69 | 70 |
71 | ) 72 | } 73 | -------------------------------------------------------------------------------- /packages/frontend/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | interface LocaleRootLayoutProps { 2 | children: React.ReactNode 3 | params: { 4 | locale: string | undefined 5 | } 6 | } 7 | 8 | export default function RootLayout({ children, params: { locale } }: LocaleRootLayoutProps) { 9 | return <>{children} 10 | } 11 | -------------------------------------------------------------------------------- /packages/frontend/src/app/navigation.ts: -------------------------------------------------------------------------------- 1 | import { createLocalizedPathnamesNavigation, Pathnames } from 'next-intl/navigation' 2 | import { locales } from '../../i18n' 3 | 4 | export const localePrefix = 'always' // Default 5 | 6 | // The `pathnames` object holds pairs of internal 7 | // and external paths, separated by locale. 8 | export const pathnames = { 9 | // If all locales use the same pathname, a 10 | // single external path can be provided. 11 | '/': '/', 12 | '/blog': '/blog', 13 | '/sign-in': '/sign-in', 14 | '/sign-up': '/sign-up', 15 | 16 | // If locales use different paths, you can 17 | // specify each external path per locale. 18 | '/about': { 19 | en: '/about', 20 | de: '/ueber-uns', 21 | }, 22 | 23 | // // Dynamic params are supported via square brackets 24 | // '/news/[articleSlug]-[articleId]': { 25 | // en: '/news/[articleSlug]-[articleId]', 26 | // de: '/neuigkeiten/[articleSlug]-[articleId]', 27 | // }, 28 | 29 | // // Also (optional) catch-all segments are supported 30 | // '/categories/[...slug]': { 31 | // en: '/categories/[...slug]', 32 | // de: '/kategorien/[...slug]', 33 | // }, 34 | } satisfies Pathnames 35 | 36 | export const { Link, redirect, usePathname, useRouter, getPathname } = 37 | createLocalizedPathnamesNavigation({ locales, localePrefix, pathnames }) 38 | -------------------------------------------------------------------------------- /packages/frontend/src/components/auth-clerk-header.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Link } from '@/app/navigation' 4 | import { OrganizationSwitcher, UserButton, useUser } from '@clerk/nextjs' 5 | import { FC } from 'react' 6 | import { buttonVariants } from './ui/button' 7 | 8 | export interface AuthClerkHeaderProps {} 9 | export const AuthClerkHeader: FC = () => { 10 | const { isLoaded, isSignedIn } = useUser() 11 | 12 | if (isLoaded && !isSignedIn) 13 | return ( 14 | 21 | Sign In 22 | 23 | ) 24 | return ( 25 | <> 26 |
27 | { 29 | if (organization) { 30 | return `/${organization.slug}/profile` 31 | } 32 | return '/' 33 | }} 34 | /> 35 | 36 |
37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /packages/frontend/src/components/cal-com.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Cal, { getCalApi } from '@calcom/embed-react' 4 | import { useTheme } from 'next-themes' 5 | import { useEffect } from 'react' 6 | 7 | export function CalCom() { 8 | const { resolvedTheme } = useTheme() 9 | 10 | console.log(resolvedTheme) 11 | 12 | useEffect(() => { 13 | ;(async function () { 14 | const cal = await getCalApi() 15 | cal('ui', { 16 | styles: { branding: { brandColor: '#111827' } }, 17 | hideEventTypeDetails: false, 18 | layout: 'month_view', 19 | theme: resolvedTheme === 'dark' ? 'dark' : 'light', 20 | }) 21 | })() 22 | }, []) 23 | 24 | return ( 25 | 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /packages/frontend/src/components/callout.tsx: -------------------------------------------------------------------------------- 1 | import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' 2 | 3 | interface CalloutProps { 4 | icon?: string 5 | title?: string 6 | children?: React.ReactNode 7 | } 8 | 9 | export function Callout({ title, children, icon, ...props }: CalloutProps) { 10 | return ( 11 | 12 | {icon &&

{icon}

} 13 | {title && {title}} 14 | {children} 15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /packages/frontend/src/components/code-block-wraper.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as React from 'react' 4 | 5 | import { Button } from '@/components/ui/button' 6 | import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' 7 | import { cn } from '@/lib/utils' 8 | 9 | interface CodeBlockProps extends React.HTMLAttributes { 10 | expandButtonTitle?: string 11 | } 12 | 13 | export function CodeBlockWrapper({ 14 | expandButtonTitle = 'View Code', 15 | className, 16 | children, 17 | ...props 18 | }: CodeBlockProps) { 19 | const [isOpened, setIsOpened] = React.useState(false) 20 | 21 | return ( 22 | 23 |
24 | 25 |
31 | {children} 32 |
33 |
34 |
40 | 41 | 44 | 45 |
46 |
47 |
48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /packages/frontend/src/components/data-table/data-table-row-actions.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from '@/components/ui/button' 4 | import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' 5 | import Link from 'next/link' 6 | import { FC, HTMLAttributeAnchorTarget, PropsWithChildren } from 'react' 7 | 8 | export interface DataTableRowActionsProps extends PropsWithChildren {} 9 | 10 | export function DataTableRowActions({ children }: DataTableRowActionsProps) { 11 | return
{children}
12 | } 13 | 14 | export interface LinkRowActionProps { 15 | href: string 16 | children?: React.ReactNode 17 | tooltip: string 18 | target?: HTMLAttributeAnchorTarget 19 | } 20 | export const LinkRowAction: FC = ({ href, tooltip, children, target }) => { 21 | return ( 22 | 23 | 24 | 25 | 26 | 27 | 28 | {tooltip} 29 | 30 | 31 | 32 | ) 33 | } 34 | 35 | export interface ButtonRowActionProps extends PropsWithChildren { 36 | tooltip: string 37 | onClick: () => void 38 | } 39 | export const ButtonRowAction: FC = ({ children, onClick, tooltip }) => { 40 | return ( 41 | 42 | 43 | 44 | 47 | 48 | {tooltip} 49 | 50 | 51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /packages/frontend/src/components/data-table/data-table-view-options.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from '@/components/ui/button' 4 | import { 5 | DropdownMenu, 6 | DropdownMenuCheckboxItem, 7 | DropdownMenuContent, 8 | DropdownMenuLabel, 9 | DropdownMenuSeparator, 10 | DropdownMenuTrigger, 11 | } from '@/components/ui/dropdown-menu' 12 | import { MixerHorizontalIcon } from '@radix-ui/react-icons' 13 | import type { Table } from '@tanstack/react-table' 14 | 15 | interface DataTableViewOptionsProps { 16 | table: Table 17 | } 18 | 19 | export function DataTableViewOptions({ 20 | table, 21 | }: DataTableViewOptionsProps) { 22 | return ( 23 | 24 | 25 | 34 | 35 | 36 | Toggle columns 37 | 38 | {table 39 | .getAllColumns() 40 | .filter( 41 | (column) => 42 | typeof column.accessorFn !== 'undefined' && column.getCanHide() 43 | ) 44 | .map((column) => { 45 | return ( 46 | column.toggleVisibility(!!value)} 51 | > 52 | {column.id} 53 | 54 | ) 55 | })} 56 | 57 | 58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /packages/frontend/src/components/featured.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import Image from 'next/image' 3 | import Link from 'next/link' 4 | import { FC } from 'react' 5 | 6 | export interface FeaturedProps {} 7 | export const Featured: FC = () => { 8 | const websites = [ 9 | { 10 | alt: 'FelixVemmer.com', 11 | src: '/personal-projects/felixvemmer-com.png', 12 | href: 'https://felixvemmer.com/?ref=cryptoneur.xyz', 13 | }, 14 | { 15 | alt: 'BacklinkGPT.com', 16 | src: '/personal-projects/backlinkgpt-com.png', 17 | href: 'https://www.backlinkgpt.com/?ref=cryptoneur.xyz', 18 | }, 19 | { 20 | alt: 'No-Code Scraper', 21 | src: '/personal-projects/nocode-scraper-com.png', 22 | href: 'https://nocodescraper.com/?ref=cryptoneur.xyz', 23 | }, 24 | ] 25 | 26 | return ( 27 |
28 |
29 |

My Other Projects

30 |
31 | {websites.map((website, index) => ( 32 |
41 | 47 | {website.alt} 48 | 49 | {website.alt} 56 | 57 |
58 | ))} 59 |
60 |
61 |
62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /packages/frontend/src/components/founders-note.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | 3 | import { Card } from '@/components/ui/card' 4 | import Image from 'next/image' 5 | 6 | export const FoundersNote: FC = () => { 7 | return ( 8 | 9 |
10 |

11 | As a web3 entrepreneur, finding the right funding opportunity for your project can be a 12 | daunting task. 13 |

14 |
15 |

16 | With so many grants available, it can be difficult to navigate and find the ones that 17 | align with your specific project and use case. Additionally, a lack of data-driven 18 | insights on past and successful grant applications can make the application process even 19 | more challenging. 20 |

21 |
22 |

23 | We understand these challenges and have created a solution. This web3 grant platform is 24 | a comprehensive and constantly updated database of web3 grants, equipped with advanced 25 | filtering options and valuable data-driven insights to make the search and application 26 | process easier for you. 27 |

28 |
29 |

30 | But our platform isn't just about providing resources - it's also about building a 31 | community. Anyone can contribute and add information to our database, making it even 32 | more complete and beneficial for all users. 33 |

34 |
35 |

36 | As a web3 entrepreneur, I understand the importance of funding and resources for the 37 | success of your project. That's why I'm committed to making Cryptoneur's web3 grant 38 | platform the go-to destination for anyone looking for funding opportunities in the web3 39 | space. 40 |

41 |
42 |
43 |
44 |
45 | Felix Vemmer 52 |
53 |
Felix Vemmer
54 |
Founder & CEO
55 |
56 |
57 |
58 |
59 | ) 60 | } 61 | -------------------------------------------------------------------------------- /packages/frontend/src/components/gas-fees-calculator/currency-input.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { usePathname } from '@/app/navigation' 4 | import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' 5 | import { Label } from '@/components/ui/label' 6 | import { 7 | Select, 8 | SelectContent, 9 | SelectItem, 10 | SelectTrigger, 11 | SelectValue, 12 | } from '@/components/ui/select' 13 | import { TGetCurrenciesResponse } from '@/data/gas-fees-calculator' 14 | import { createUrl } from '@/lib/utils' 15 | import { useRouter, useSearchParams } from 'next/navigation' 16 | 17 | export default function CurrencyInput({ currencies }: { currencies: TGetCurrenciesResponse }) { 18 | const pathanme = usePathname() 19 | const searchParams = useSearchParams() 20 | const router = useRouter() 21 | 22 | const currency = searchParams?.get('currency') 23 | 24 | const newSearchParams = new URLSearchParams(searchParams?.toString() ?? '') 25 | 26 | return ( 27 | <> 28 | 29 | 30 | Local Currency 31 | 32 | Select the currency you want the fees to be displayed in. 33 | 34 | 35 | 36 | 37 | 59 | 60 | 61 | 62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /packages/frontend/src/components/gas-fees-calculator/fees-form-card.tsx: -------------------------------------------------------------------------------- 1 | import { FC, PropsWithChildren } from 'react' 2 | 3 | export interface FeesFormCardProps extends PropsWithChildren { 4 | title: string 5 | description: string 6 | } 7 | export const FeesFormCard: FC = ({ title, description, children }) => { 8 | return ( 9 |
10 |
11 |
12 |

{title}

13 |

{description}

14 |
15 |
16 |
17 |
{children}
18 |
19 |
20 |
21 |
22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /packages/frontend/src/components/gas-fees-calculator/fees-form.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { FC, PropsWithChildren } from 'react' 4 | import { FormProvider, useForm } from 'react-hook-form' 5 | 6 | export interface FeesFormProps extends PropsWithChildren { 7 | txnTypes: 8 | | { 9 | name: string 10 | gas: number 11 | }[] 12 | | undefined 13 | } 14 | export const FeesForm: FC = ({ children, txnTypes }) => { 15 | if (!txnTypes) { 16 | throw new Error('txnTypes is required') 17 | } 18 | 19 | const methods = useForm({ 20 | defaultValues: { 21 | currency: 'USD', 22 | usedGas: txnTypes[0].gas, 23 | txnType: txnTypes[0], 24 | gasPrice: 'standard', 25 | }, 26 | }) 27 | 28 | return ( 29 | 30 |
31 |
{children}
32 |
33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /packages/frontend/src/components/gas-fees-calculator/gas-price-radio.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { createUrl } from '@/lib/utils' 4 | import { usePathname, useRouter, useSearchParams } from 'next/navigation' 5 | import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card' 6 | import { Label } from '../ui/label' 7 | import { RadioGroup, RadioGroupItem } from '../ui/radio-group' 8 | 9 | export const GasPriceRadio = ({}) => { 10 | const gasPriceOption = ['standard', 'fast', 'instant'] 11 | 12 | const searchParams = useSearchParams() 13 | const pathanme = usePathname() 14 | const router = useRouter() 15 | 16 | return ( 17 | 18 | 19 | Gas Price 20 | Select the transaction speed you want to use. 21 | 22 | 23 |
24 | 25 | { 29 | if (!searchParams || !pathanme) return 30 | 31 | const newSearchParams = new URLSearchParams(searchParams?.toString() ?? '') 32 | 33 | newSearchParams.set('gasPrice', value) 34 | router.push(createUrl(pathanme, newSearchParams), { 35 | scroll: false, 36 | }) 37 | }} 38 | > 39 | {gasPriceOption.map((option) => ( 40 |
41 | 42 | 45 |
46 | ))} 47 |
48 |
49 |
50 |
51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /packages/frontend/src/components/gas-fees-calculator/gitcoin-grant.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | import { FC } from 'react' 3 | 4 | interface Translation { 5 | gitcoin_title: string 6 | } 7 | 8 | interface Data { 9 | translations: Translation[] 10 | gitcoin_logo: { 11 | id: string 12 | } 13 | } 14 | 15 | export const GitcoinGrant: FC = async () => { 16 | return ( 17 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /packages/frontend/src/components/iframe.tsx: -------------------------------------------------------------------------------- 1 | import Script from 'next/script' 2 | import { FC } from 'react' 3 | 4 | export interface IframeProps { 5 | src: string 6 | className?: string 7 | } 8 | 9 | export const Iframe: FC = ({ src, className }) => { 10 | return ( 11 |
21 | 36 |
37 |
38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /packages/frontend/src/components/language-toggle.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from '@/components/ui/button' 4 | import { 5 | DropdownMenu, 6 | DropdownMenuContent, 7 | DropdownMenuItem, 8 | DropdownMenuTrigger, 9 | } from '@/components/ui/dropdown-menu' 10 | import { useParams, useRouter } from 'next/navigation' 11 | import { locales } from '../../i18n' 12 | 13 | export function LanguageToggle() { 14 | const params = useParams() 15 | const router = useRouter() 16 | 17 | const locale = typeof params?.locale === 'string' ? params?.locale : 'en' 18 | 19 | const changeLanguage = (lang: string) => { 20 | router.push(`/${lang}`, { 21 | scroll: false, 22 | }) 23 | router.refresh() 24 | // router.push(router.asPath, router.asPath, { locale: lang }) 25 | } 26 | 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | {locales.map((lang) => ( 34 | changeLanguage(lang)}> 35 | {lang} 36 | 37 | ))} 38 | 39 | 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /packages/frontend/src/components/link-button.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import Link from 'next/link' 3 | import { FC } from 'react' 4 | import { ButtonProps, buttonVariants } from './ui/button' 5 | 6 | export interface LinkButtonProps extends ButtonProps { 7 | href: string 8 | label: string 9 | } 10 | export const LinkButton: FC = ({ label, href, variant, size, className }) => { 11 | return ( 12 | 13 | {label} 14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /packages/frontend/src/components/main-nav.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Link } from '@/app/navigation' 4 | import { navigationConfig } from '@/config/navigation' 5 | import { siteConfig } from '@/config/site' 6 | import { cn } from '@/lib/utils' 7 | import { Rocket } from 'lucide-react' 8 | import { useParams, usePathname } from 'next/navigation' 9 | 10 | export function MainNav() { 11 | const pathname = usePathname() 12 | const params = useParams() 13 | 14 | const locale = typeof params?.locale === 'string' ? params?.locale : 'en' 15 | 16 | return ( 17 |
18 | 19 | 20 | {siteConfig.name} 21 | 22 | 41 |
42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /packages/frontend/src/components/mdx-card.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | interface CardProps extends React.HTMLAttributes { 6 | href?: string 7 | disabled?: boolean 8 | } 9 | 10 | export function MdxCard({ href, className, children, disabled, ...props }: CardProps) { 11 | return ( 12 |
20 |
21 |
22 | {children} 23 |
24 |
25 | {href && ( 26 | 27 | View 28 | 29 | )} 30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /packages/frontend/src/components/mode-toggle.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { MoonIcon, SunIcon } from '@radix-ui/react-icons' 4 | import { useTheme } from 'next-themes' 5 | 6 | import { Button } from '@/components/ui/button' 7 | import { 8 | DropdownMenu, 9 | DropdownMenuContent, 10 | DropdownMenuItem, 11 | DropdownMenuTrigger, 12 | } from '@/components/ui/dropdown-menu' 13 | 14 | export function ModeToggle() { 15 | const { setTheme } = useTheme() 16 | 17 | return ( 18 | 19 | 20 | 25 | 26 | 27 | setTheme('light')}>Light 28 | setTheme('dark')}>Dark 29 | setTheme('system')}>System 30 | 31 | 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /packages/frontend/src/components/page-header.tsx: -------------------------------------------------------------------------------- 1 | import Balance from 'react-wrap-balancer' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | function PageHeader({ className, children, ...props }: React.HTMLAttributes) { 6 | return ( 7 |
14 | {children} 15 |
16 | ) 17 | } 18 | 19 | interface PageHeaderHeadingProps extends React.HTMLAttributes { 20 | level?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' 21 | className?: string 22 | } 23 | 24 | function PageHeaderHeading({ level = 'h1', className, ...props }: PageHeaderHeadingProps) { 25 | const HeadingTag = level 26 | return ( 27 | 36 | ) 37 | } 38 | 39 | function PageHeaderDescription({ 40 | className, 41 | ...props 42 | }: React.HTMLAttributes) { 43 | return ( 44 | 51 | ) 52 | } 53 | 54 | function PageActions({ className, ...props }: React.HTMLAttributes) { 55 | return ( 56 |
60 | ) 61 | } 62 | 63 | export { PageActions, PageHeader, PageHeaderDescription, PageHeaderHeading } 64 | -------------------------------------------------------------------------------- /packages/frontend/src/components/posthog-page-view.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { usePathname, useSearchParams } from 'next/navigation' 4 | import { usePostHog } from 'posthog-js/react' 5 | import { useEffect } from 'react' 6 | 7 | export default function PostHogPageView() { 8 | const pathname = usePathname() 9 | const searchParams = useSearchParams() 10 | const posthog = usePostHog() 11 | // Track pageviews 12 | useEffect(() => { 13 | if (pathname && posthog) { 14 | let url = window.origin + pathname 15 | if (searchParams && searchParams.toString()) { 16 | url = url + `?${searchParams.toString()}` 17 | } 18 | posthog.capture('$pageview', { 19 | $current_url: url, 20 | }) 21 | } 22 | }, [pathname, searchParams, posthog]) 23 | 24 | return null 25 | } 26 | -------------------------------------------------------------------------------- /packages/frontend/src/components/posthog-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { absoluteUrl } from '@/lib/utils' 4 | import posthog from 'posthog-js' 5 | import { PostHogProvider } from 'posthog-js/react' 6 | 7 | const posthogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY 8 | const posthogHost = absoluteUrl('/ingest') 9 | 10 | if (!posthogKey) throw new Error('NEXT_PUBLIC_POSTHOG_KEY is not set') 11 | if (!posthogHost) throw new Error('NEXT_PUBLIC_POSTHOG_HOST is not set') 12 | 13 | if (typeof window !== 'undefined') { 14 | // console.log('posthogHost', posthogHost) 15 | posthog.init(posthogKey, { 16 | api_host: posthogHost, 17 | capture_pageview: false, // Disable automatic pageview capture, as we capture manually 18 | // Enable debug mode in development 19 | // loaded: (posthog) => { 20 | // if (process.env.NODE_ENV === 'development') posthog.debug() 21 | // }, 22 | }) 23 | } 24 | 25 | export function PHProvider({ children }: { children: React.ReactNode }) { 26 | return {children} 27 | } 28 | -------------------------------------------------------------------------------- /packages/frontend/src/components/providers.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { ThemeProvider as NextThemesProvider } from 'next-themes' 4 | import { ThemeProviderProps } from 'next-themes/dist/types' 5 | import { TooltipProvider } from './ui/tooltip' 6 | 7 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 8 | return ( 9 | 10 | {children} 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /packages/frontend/src/components/related-post-card.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * v0 by Vercel. 3 | * @see https://v0.dev/t/SvZjaEpu0ds 4 | */ 5 | import { Card } from '@/components/ui/card' 6 | import { formatDate } from '@/lib/utils' 7 | import { allPosts } from 'contentlayer/generated' 8 | import Image from 'next/image' 9 | import Link from 'next/link' 10 | 11 | interface RelatedPostCardProps { 12 | slug: string 13 | } 14 | 15 | export function RelatedPostCard({ slug }: RelatedPostCardProps) { 16 | const post = allPosts.find((p) => p.slug === slug) 17 | 18 | if (!post) { 19 | throw new Error(`Cannot find post with slug "${slug}"`) 20 | } 21 | 22 | return ( 23 | 24 | 25 |
26 | blog cover 37 |
38 |
39 |

{post.title}

40 |

{post.description}

41 |
42 |
43 | {formatDate(post.date)} 44 |
45 |
46 |
47 |
48 | 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /packages/frontend/src/components/site-footer.tsx: -------------------------------------------------------------------------------- 1 | import { siteConfig } from '@/config/site' 2 | 3 | export function SiteFooter() { 4 | return ( 5 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /packages/frontend/src/components/site-header.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | import { Icons } from '@/components/icons' 4 | import { ModeToggle } from '@/components/mode-toggle' 5 | import { buttonVariants } from '@/components/ui/button' 6 | import { siteConfig } from '@/config/site' 7 | import { cn } from '@/lib/utils' 8 | import { AuthClerkHeader } from './auth-clerk-header' 9 | import { LanguageToggle } from './language-toggle' 10 | import { MainNav } from './main-nav' 11 | import { MobileNav } from './mobile-nav' 12 | 13 | export async function SiteHeader() { 14 | return ( 15 |
16 |
17 | 18 | 19 |
20 | {/* TODO: Bring Search Bar back */} 21 | {/*
22 | 23 |
*/} 24 | 68 |
69 |
70 |
71 | ) 72 | } 73 | -------------------------------------------------------------------------------- /packages/frontend/src/components/tables/grants.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { DataTable } from '@/components/data-table/data-table' 4 | import { TGetGrantsResponse, TGrant } from '@/data/grants' 5 | import { useDataTable } from '@/hooks/use-data-table' 6 | import { DataTableFilterField } from '@/types' 7 | import * as React from 'react' 8 | import { getColumns } from '../column-defs/grants' 9 | import { DataTableToolbar } from '../data-table/data-table-toolbar' 10 | 11 | interface CampaignsTableProps { 12 | dataPromise: Promise 13 | } 14 | 15 | export function GrantsTable({ dataPromise }: CampaignsTableProps) { 16 | // Learn more about React.use here: https://react.dev/reference/react/use 17 | const { grants, cachedBlockchainOptions, cachedUseCasesOptions, cachedCategoriesOptions } = 18 | React.use(dataPromise) 19 | 20 | const { data, pageCount } = grants 21 | 22 | const filterFields: DataTableFilterField[] = [ 23 | { 24 | label: 'Grant Name', 25 | value: 'grantName', 26 | placeholder: 'Filter grant names...', 27 | }, 28 | { 29 | label: 'Blockchain', 30 | value: 'grantBlockchainNames', 31 | options: cachedBlockchainOptions, 32 | }, 33 | { 34 | label: 'Use Case', 35 | value: 'grantUseCaseNames', 36 | options: cachedUseCasesOptions, 37 | }, 38 | { 39 | label: 'Category', 40 | value: 'grantCategoryNames', 41 | options: cachedCategoriesOptions, 42 | }, 43 | ] 44 | 45 | // Memoize the columns so they don't re-render on every render 46 | const columns = React.useMemo(() => getColumns(), []) 47 | const { table } = useDataTable({ 48 | data, 49 | columns, 50 | pageCount, 51 | // optional props 52 | filterFields, 53 | // enableAdvancedFilter: featureFlags.includes("advancedFilter"), 54 | defaultPerPage: 10, 55 | defaultSort: 'grantName.asc', 56 | }) 57 | 58 | return ( 59 |
60 | 61 | {/* */} 62 | 63 | 68 | // ) : null 69 | // } 70 | /> 71 |
72 | ) 73 | } 74 | -------------------------------------------------------------------------------- /packages/frontend/src/components/tailwind-indicator.tsx: -------------------------------------------------------------------------------- 1 | export function TailwindIndicator() { 2 | if (process.env.NODE_ENV === 'production') return null 3 | 4 | return ( 5 |
6 |
xs
7 |
sm
8 |
md
9 |
lg
10 |
xl
11 |
2xl
12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /packages/frontend/src/components/theme-provider.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feliche93/cryptoneur/f565b6de72aab6d56d3c738bd59568de26b4c9f0/packages/frontend/src/components/theme-provider.tsx -------------------------------------------------------------------------------- /packages/frontend/src/components/theme-switcher.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useSelectedLayoutSegment } from 'next/navigation' 4 | import * as React from 'react' 5 | 6 | import { useConfig } from '@/hooks/use-config' 7 | 8 | export function ThemeSwitcher() { 9 | const [config] = useConfig() 10 | const segment = useSelectedLayoutSegment() 11 | 12 | React.useEffect(() => { 13 | document.body.classList.forEach((className) => { 14 | if (className.match(/^theme.*/)) { 15 | document.body.classList.remove(className) 16 | } 17 | }) 18 | 19 | const theme = segment === 'themes' ? config.theme : null 20 | if (theme) { 21 | return document.body.classList.add(`theme-${theme}`) 22 | } 23 | }, [segment, config]) 24 | 25 | return null 26 | } 27 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/accordion.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AccordionPrimitive from "@radix-ui/react-accordion" 5 | import { ChevronDown } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Accordion = AccordionPrimitive.Root 10 | 11 | const AccordionItem = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef 14 | >(({ className, ...props }, ref) => ( 15 | 20 | )) 21 | AccordionItem.displayName = "AccordionItem" 22 | 23 | const AccordionTrigger = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, children, ...props }, ref) => ( 27 | 28 | svg]:rotate-180", 32 | className 33 | )} 34 | {...props} 35 | > 36 | {children} 37 | 38 | 39 | 40 | )) 41 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 42 | 43 | const AccordionContent = React.forwardRef< 44 | React.ElementRef, 45 | React.ComponentPropsWithoutRef 46 | >(({ className, children, ...props }, ref) => ( 47 | 52 |
{children}
53 |
54 | )) 55 | 56 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 57 | 58 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } 59 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/alert.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const alertVariants = cva( 7 | "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", 8 | { 9 | variants: { 10 | variant: { 11 | default: "bg-background text-foreground", 12 | destructive: 13 | "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", 14 | }, 15 | }, 16 | defaultVariants: { 17 | variant: "default", 18 | }, 19 | } 20 | ) 21 | 22 | const Alert = React.forwardRef< 23 | HTMLDivElement, 24 | React.HTMLAttributes & VariantProps 25 | >(({ className, variant, ...props }, ref) => ( 26 |
32 | )) 33 | Alert.displayName = "Alert" 34 | 35 | const AlertTitle = React.forwardRef< 36 | HTMLParagraphElement, 37 | React.HTMLAttributes 38 | >(({ className, ...props }, ref) => ( 39 |
44 | )) 45 | AlertTitle.displayName = "AlertTitle" 46 | 47 | const AlertDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |
56 | )) 57 | AlertDescription.displayName = "AlertDescription" 58 | 59 | export { Alert, AlertTitle, AlertDescription } 60 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Avatar = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | Avatar.displayName = AvatarPrimitive.Root.displayName 22 | 23 | const AvatarImage = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 32 | )) 33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 34 | 35 | const AvatarFallback = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | )) 48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 49 | 50 | export { Avatar, AvatarImage, AvatarFallback } 51 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import { cva, type VariantProps } from 'class-variance-authority' 2 | import * as React from 'react' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const badgeVariants = cva( 7 | 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 8 | { 9 | variants: { 10 | variant: { 11 | default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', 12 | secondary: 13 | 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', 14 | destructive: 15 | 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', 16 | outline: 'text-foreground', 17 | }, 18 | }, 19 | defaultVariants: { 20 | variant: 'default', 21 | }, 22 | }, 23 | ) 24 | 25 | export interface BadgeProps 26 | extends React.HTMLAttributes, 27 | VariantProps {} 28 | 29 | function Badge({ className, variant, ...props }: BadgeProps) { 30 | return
31 | } 32 | 33 | export { Badge, badgeVariants } 34 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/border.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | 3 | type BorderProps = { 4 | as?: T 5 | className?: string 6 | position?: 'top' | 'left' 7 | invert?: boolean 8 | } 9 | 10 | export function Border({ 11 | as, 12 | className, 13 | position = 'top', 14 | invert = false, 15 | ...props 16 | }: Omit, keyof BorderProps> & BorderProps) { 17 | let Component = as ?? 'div' 18 | 19 | return ( 20 | 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | const Card = React.forwardRef>( 6 | ({ className, ...props }, ref) => ( 7 |
12 | ), 13 | ) 14 | Card.displayName = 'Card' 15 | 16 | const CardHeader = React.forwardRef>( 17 | ({ className, ...props }, ref) => ( 18 |
19 | ), 20 | ) 21 | CardHeader.displayName = 'CardHeader' 22 | 23 | const CardTitle = React.forwardRef>( 24 | ({ className, ...props }, ref) => ( 25 |

30 | ), 31 | ) 32 | CardTitle.displayName = 'CardTitle' 33 | 34 | const CardDescription = React.forwardRef< 35 | HTMLParagraphElement, 36 | React.HTMLAttributes 37 | >(({ className, ...props }, ref) => ( 38 |

39 | )) 40 | CardDescription.displayName = 'CardDescription' 41 | 42 | const CardContent = React.forwardRef>( 43 | ({ className, ...props }, ref) => ( 44 |

45 | ), 46 | ) 47 | CardContent.displayName = 'CardContent' 48 | 49 | const CardFooter = React.forwardRef>( 50 | ({ className, ...props }, ref) => ( 51 |
52 | ), 53 | ) 54 | CardFooter.displayName = 'CardFooter' 55 | 56 | export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } 57 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 5 | import { Check } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Checkbox = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 21 | 24 | 25 | 26 | 27 | )) 28 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 29 | 30 | export { Checkbox } 31 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/container.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | 3 | type ContainerProps = { 4 | as?: T 5 | className?: string 6 | children: React.ReactNode 7 | } 8 | 9 | export function Container({ 10 | as, 11 | className, 12 | children, 13 | }: Omit, keyof ContainerProps> & ContainerProps) { 14 | let Component = as ?? 'div' 15 | 16 | return ( 17 | 18 |
{children}
19 |
20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/fade-in.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion, useReducedMotion } from 'framer-motion' 4 | import { createContext, useContext } from 'react' 5 | 6 | const FadeInStaggerContext = createContext(false) 7 | 8 | const viewport = { once: true, margin: '0px 0px -200px' } 9 | 10 | export function FadeIn(props: React.ComponentPropsWithoutRef) { 11 | let shouldReduceMotion = useReducedMotion() 12 | let isInStaggerGroup = useContext(FadeInStaggerContext) 13 | 14 | return ( 15 | 30 | ) 31 | } 32 | 33 | export function FadeInStagger({ 34 | faster = false, 35 | ...props 36 | }: React.ComponentPropsWithoutRef & { faster?: boolean }) { 37 | return ( 38 | 39 | 46 | 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/header.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import * as React from 'react' 3 | 4 | interface HeaderProps extends React.HTMLAttributes { 5 | Title?: typeof Title 6 | Section?: typeof Section 7 | } 8 | 9 | const Header = React.forwardRef(({ className, ...props }, ref) => ( 10 |
11 | )) as React.ForwardRefExoticComponent> & { 12 | Title: typeof Title 13 | Section: typeof Section 14 | } 15 | 16 | Header.displayName = 'Header' 17 | 18 | const Section = React.forwardRef>( 19 | ({ className, ...props }, ref) => ( 20 |

28 | ), 29 | ) 30 | 31 | Section.displayName = 'Header.Section' 32 | 33 | const Title = React.forwardRef>( 34 | ({ className, ...props }, ref) => ( 35 |
40 | ), 41 | ) 42 | 43 | Title.displayName = 'Header.Title' 44 | 45 | Header.Title = Title 46 | Header.Section = Section 47 | 48 | export { Header } 49 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/hover-card.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as HoverCardPrimitive from "@radix-ui/react-hover-card" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const HoverCard = HoverCardPrimitive.Root 9 | 10 | const HoverCardTrigger = HoverCardPrimitive.Trigger 11 | 12 | const HoverCardContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 26 | )) 27 | HoverCardContent.displayName = HoverCardPrimitive.Content.displayName 28 | 29 | export { HoverCard, HoverCardTrigger, HoverCardContent } 30 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | export interface InputProps extends React.InputHTMLAttributes {} 6 | 7 | const Input = React.forwardRef( 8 | ({ className, type, ...props }, ref) => { 9 | return ( 10 | 19 | ) 20 | }, 21 | ) 22 | Input.displayName = 'Input' 23 | 24 | export { Input } 25 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/list.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | 3 | import { Border } from '@/components/ui/border' 4 | import { FadeIn, FadeInStagger } from '@/components/ui/fade-in' 5 | 6 | export function List({ children, className }: { children: React.ReactNode; className?: string }) { 7 | return ( 8 | 9 |
    10 | {children} 11 |
12 |
13 | ) 14 | } 15 | 16 | export function ListItem({ children, title }: { children: React.ReactNode; title?: string }) { 17 | return ( 18 |
  • 19 | 20 | 21 | {title && {`${title}. `}} 22 | {children} 23 | 24 | 25 |
  • 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/page-intro.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | 3 | import { Container } from '@/components/ui/container' 4 | import { FadeIn } from '@/components/ui/fade-in' 5 | import { cn } from '@/lib/utils' 6 | 7 | export function PageIntro({ 8 | eyebrow, 9 | title, 10 | className, 11 | children, 12 | centered = false, 13 | }: { 14 | eyebrow: string 15 | title: string 16 | className?: string 17 | children?: React.ReactNode 18 | centered?: boolean 19 | }) { 20 | return ( 21 | 22 | 23 |

    24 | 25 | {eyebrow} 26 | 27 | - 28 | 34 | {title} 35 | 36 |

    37 | {children && ( 38 |
    41 | {children} 42 |
    43 | )} 44 |
    45 |
    46 | ) 47 | } 48 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as PopoverPrimitive from "@radix-ui/react-popover" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Popover = PopoverPrimitive.Root 9 | 10 | const PopoverTrigger = PopoverPrimitive.Trigger 11 | 12 | const PopoverContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 17 | 27 | 28 | )) 29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 30 | 31 | export { Popover, PopoverTrigger, PopoverContent } 32 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/radio-group.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" 5 | import { Circle } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const RadioGroup = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => { 13 | return ( 14 | 19 | ) 20 | }) 21 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName 22 | 23 | const RadioGroupItem = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => { 27 | return ( 28 | 36 | 37 | 38 | 39 | 40 | ) 41 | }) 42 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName 43 | 44 | export { RadioGroup, RadioGroupItem } 45 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/scroll-area.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const ScrollArea = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, children, ...props }, ref) => ( 12 | 17 | 18 | {children} 19 | 20 | 21 | 22 | 23 | )) 24 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName 25 | 26 | const ScrollBar = React.forwardRef< 27 | React.ElementRef, 28 | React.ComponentPropsWithoutRef 29 | >(({ className, orientation = "vertical", ...props }, ref) => ( 30 | 43 | 44 | 45 | )) 46 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName 47 | 48 | export { ScrollArea, ScrollBar } 49 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | 3 | function Skeleton({ className, ...props }: React.HTMLAttributes) { 4 | return
    5 | } 6 | 7 | export { Skeleton } 8 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/slider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SliderPrimitive from "@radix-ui/react-slider" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Slider = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | 21 | 22 | 23 | 24 | 25 | )) 26 | Slider.displayName = SliderPrimitive.Root.displayName 27 | 28 | export { Slider } 29 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useTheme } from "next-themes" 4 | import { Toaster as Sonner } from "sonner" 5 | 6 | type ToasterProps = React.ComponentProps 7 | 8 | const Toaster = ({ ...props }: ToasterProps) => { 9 | const { theme = "system" } = useTheme() 10 | 11 | return ( 12 | 28 | ) 29 | } 30 | 31 | export { Toaster } 32 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SwitchPrimitives from "@radix-ui/react-switch" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Switch = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | 25 | 26 | )) 27 | Switch.displayName = SwitchPrimitives.Root.displayName 28 | 29 | export { Switch } 30 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/tabs.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as TabsPrimitive from "@radix-ui/react-tabs" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Tabs = TabsPrimitive.Root 9 | 10 | const TabsList = React.forwardRef< 11 | React.ElementRef, 12 | React.ComponentPropsWithoutRef 13 | >(({ className, ...props }, ref) => ( 14 | 22 | )) 23 | TabsList.displayName = TabsPrimitive.List.displayName 24 | 25 | const TabsTrigger = React.forwardRef< 26 | React.ElementRef, 27 | React.ComponentPropsWithoutRef 28 | >(({ className, ...props }, ref) => ( 29 | 37 | )) 38 | TabsTrigger.displayName = TabsPrimitive.Trigger.displayName 39 | 40 | const TabsContent = React.forwardRef< 41 | React.ElementRef, 42 | React.ComponentPropsWithoutRef 43 | >(({ className, ...props }, ref) => ( 44 | 52 | )) 53 | TabsContent.displayName = TabsPrimitive.Content.displayName 54 | 55 | export { Tabs, TabsList, TabsTrigger, TabsContent } 56 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/tag-list.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | import { Badge } from './badge' 3 | 4 | export function TagList({ 5 | children, 6 | className, 7 | }: { 8 | children: React.ReactNode 9 | className?: string 10 | }) { 11 | return ( 12 |
      13 | {children} 14 |
    15 | ) 16 | } 17 | 18 | export function TagListItem({ 19 | children, 20 | className, 21 | }: { 22 | children: React.ReactNode 23 | className?: string 24 | }) { 25 | return {children} 26 | } 27 | -------------------------------------------------------------------------------- /packages/frontend/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | export interface TextareaProps extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |