├── .nvmrc ├── store ├── index.ts └── colorStore.ts ├── lib ├── constants.ts ├── validations │ ├── auth.ts │ ├── user.ts │ ├── search-generations.ts │ ├── generate.ts │ ├── og.ts │ └── post.ts ├── exceptions.ts ├── stripe.ts ├── session.ts ├── supabase.ts ├── db.ts ├── client-helpers.ts ├── upstash.ts ├── subscription.ts ├── toc.ts ├── generations.ts ├── auth.ts ├── open-ai-stream.ts └── utils.ts ├── .prettierignore ├── .commitlintrc.json ├── public ├── emm.jpg ├── anime.png ├── sam.jpeg ├── energy.png ├── favicon.png ├── hassan.jpeg ├── shadcn.jpeg ├── shield1.png ├── steven.jpeg ├── landscape.png ├── pixelfy-og.png ├── warhammer.png ├── favicon-16x16.png ├── favicon-32x32.png ├── scenario-logo.png ├── cyberpunk-robot.png ├── apple-touch-icon.png ├── character-portrait.png ├── pixel-background.png ├── anime-cyberpunk-girl.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── examples │ ├── animeStyle │ │ ├── dbz.png │ │ ├── anime.png │ │ ├── levi.png │ │ ├── anime-girl.png │ │ ├── fullmetal.png │ │ ├── anime-boy-1.png │ │ ├── anime-boy-2.png │ │ ├── fullmetal-2.png │ │ ├── demon-slayer-1.png │ │ ├── demon-slayer-2.png │ │ ├── demon-slayer-3.png │ │ ├── demon-slayer-4.png │ │ └── hunter-x-hunter.png │ ├── fantasyRpg │ │ ├── lux.png │ │ ├── neo.png │ │ ├── owl.png │ │ ├── ekko.png │ │ ├── vayne.png │ │ ├── anduinn.png │ │ ├── illidan.png │ │ ├── thrall.png │ │ ├── deathwing.png │ │ ├── lich-king.png │ │ ├── scrapyard.png │ │ ├── warhammer.png │ │ └── anime-cyberpunk-girl.png │ ├── shields │ │ ├── shield1.png │ │ ├── shield2.png │ │ ├── shield3.png │ │ ├── shield4.png │ │ └── shield5.png │ ├── skillArt │ │ ├── skull1.png │ │ ├── skull2.png │ │ ├── skull3.png │ │ ├── skull4.png │ │ ├── frostbolt1.png │ │ ├── frostbolt2.png │ │ ├── frostbolt3.png │ │ └── frostbolt4.png │ ├── landscapePortrait │ │ ├── tower.png │ │ ├── gothic-1.png │ │ ├── gothic-2.png │ │ ├── gothic-3.png │ │ ├── gothic-4.png │ │ ├── horde-1.png │ │ ├── horde-2.png │ │ ├── horde-3.png │ │ ├── horde-4.png │ │ ├── farmhouse.png │ │ ├── bladerunner-1.png │ │ ├── bladerunner-2.png │ │ ├── bladerunner-3.png │ │ └── bladerunner-4.png │ └── pixelPortrait │ │ ├── energy-2.png │ │ ├── energy-3.png │ │ └── energy-4.png ├── images │ ├── avatars │ │ └── shadcn.png │ └── blog │ │ ├── blog-post-1.jpg │ │ ├── blog-post-2.jpg │ │ ├── blog-post-3.jpg │ │ └── blog-post-4.jpg ├── site.webmanifest └── vercel.svg ├── app ├── opengraph-image.jpg ├── (auth) │ ├── layout.tsx │ ├── login │ │ └── page.tsx │ └── register │ │ └── page.tsx ├── robots.ts ├── (dashboard) │ └── dashboard │ │ ├── loading.tsx │ │ ├── refer-users │ │ └── loading.tsx │ │ ├── generations │ │ └── loading.tsx │ │ ├── page.tsx │ │ └── layout.tsx ├── i │ └── [id] │ │ ├── loading.tsx │ │ └── layout.tsx ├── (examples) │ ├── examples │ │ └── layout.tsx │ └── layout.tsx ├── (marketing) │ └── layout.tsx ├── (credits) │ └── credits │ │ ├── layout.tsx │ │ └── page.tsx ├── sitemap.ts ├── api │ ├── users │ │ ├── [userId] │ │ │ └── route.ts │ │ └── stripe │ │ │ └── route.ts │ ├── auth │ │ └── [...nextauth] │ │ │ └── _route.tsx │ ├── generate │ │ └── prompt-generate │ │ │ └── route.ts │ └── feedback │ │ └── route.ts └── (legal) │ └── layout.tsx ├── .husky ├── commit-msg └── pre-commit ├── assets └── fonts │ ├── Inter-Bold.ttf │ ├── Inter-Regular.ttf │ ├── CalSans-SemiBold.ttf │ ├── CalSans-SemiBold.woff │ └── CalSans-SemiBold.woff2 ├── postcss.config.js ├── .prettierrc ├── prisma └── migrations │ ├── migration_lock.toml │ ├── 20221118173244_add_stripe_columns │ └── migration.sql │ └── 20221021182747_init │ └── migration.sql ├── mailing.config.json ├── components ├── analytics.tsx ├── ui │ ├── aspect-ratio.tsx │ ├── skeleton.tsx │ ├── collapsible.tsx │ ├── label.tsx │ ├── separator.tsx │ ├── progress.tsx │ ├── input.tsx │ ├── textarea.tsx │ ├── toaster.tsx │ ├── hover-card.tsx │ ├── checkbox.tsx │ ├── tooltip.tsx │ ├── popover.tsx │ ├── slider.tsx │ ├── badge.tsx │ ├── switch.tsx │ ├── radio-group.tsx │ ├── avatar.tsx │ ├── toggle.tsx │ ├── scroll-area.tsx │ ├── alert.tsx │ ├── button.tsx │ ├── tabs.tsx │ ├── card.tsx │ ├── accordion.tsx │ └── calendar.tsx ├── session-provider.tsx ├── pixelated-image.tsx ├── shell.tsx ├── theme-provider.tsx ├── card-skeleton.tsx ├── login-button.tsx ├── page-header.tsx ├── callout.tsx ├── header.tsx ├── user-avatar.tsx ├── download-image-button.tsx ├── carbon.tsx ├── modal.tsx ├── mdx-card.tsx ├── model-select-button.tsx ├── search.tsx ├── stats.tsx ├── motion-card-hover.tsx ├── copy-link-button.tsx ├── nav.tsx ├── stripe-pricing-table.tsx ├── mode-toggle.tsx ├── mobile-nav.tsx ├── search-generations-input.tsx ├── background.module.css ├── remove-background-button.tsx ├── sidebar-nav.tsx ├── images-selector.tsx ├── empty-placeholder.tsx ├── guidance-selector.tsx ├── image-influence-slider.tsx ├── image-amount-selector.tsx ├── sampling-step-selector.tsx ├── main-nav.tsx ├── generations-pagination.tsx ├── billing-form.tsx ├── toc.tsx ├── site-footer.tsx └── user-name-form.tsx ├── .editorconfig ├── hooks ├── use-mounted.ts └── use-lock-body.ts ├── config ├── marketing.ts ├── subscriptions.ts ├── site.ts ├── docs.ts └── dashboard.ts ├── types ├── next-auth.d.ts ├── index.d.ts └── scenario.ts ├── emails ├── previews │ └── Account.tsx ├── components │ ├── theme.ts │ ├── Text.tsx │ ├── Divider.tsx │ ├── Header.tsx │ ├── Footer.tsx │ └── ButtonPrimary.tsx ├── index.ts └── LoginLink.tsx ├── next.config.mjs ├── .gitignore ├── pages └── api │ └── cron │ └── index.ts ├── .eslintrc.json ├── prettier.config.js ├── tsconfig.json ├── styles └── mdx.css ├── middleware.ts └── .env.example /.nvmrc: -------------------------------------------------------------------------------- 1 | v16.18.0 2 | -------------------------------------------------------------------------------- /store/index.ts: -------------------------------------------------------------------------------- 1 | export { useColorStore } from "./colorStore" 2 | -------------------------------------------------------------------------------- /lib/constants.ts: -------------------------------------------------------------------------------- 1 | export const LOCALHOST_IP = "98.234.147.44" 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .next 4 | build 5 | .contentlayer -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /public/emm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/emm.jpg -------------------------------------------------------------------------------- /public/anime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/anime.png -------------------------------------------------------------------------------- /public/sam.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/sam.jpeg -------------------------------------------------------------------------------- /public/energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/energy.png -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/hassan.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/hassan.jpeg -------------------------------------------------------------------------------- /public/shadcn.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/shadcn.jpeg -------------------------------------------------------------------------------- /public/shield1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/shield1.png -------------------------------------------------------------------------------- /public/steven.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/steven.jpeg -------------------------------------------------------------------------------- /public/landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/landscape.png -------------------------------------------------------------------------------- /public/pixelfy-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/pixelfy-og.png -------------------------------------------------------------------------------- /public/warhammer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/warhammer.png -------------------------------------------------------------------------------- /app/opengraph-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/app/opengraph-image.jpg -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/scenario-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/scenario-logo.png -------------------------------------------------------------------------------- /public/cyberpunk-robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/cyberpunk-robot.png -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx pretty-quick --staged 5 | -------------------------------------------------------------------------------- /assets/fonts/Inter-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/assets/fonts/Inter-Bold.ttf -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/character-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/character-portrait.png -------------------------------------------------------------------------------- /public/pixel-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/pixel-background.png -------------------------------------------------------------------------------- /assets/fonts/Inter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/assets/fonts/Inter-Regular.ttf -------------------------------------------------------------------------------- /public/anime-cyberpunk-girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/anime-cyberpunk-girl.png -------------------------------------------------------------------------------- /assets/fonts/CalSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/assets/fonts/CalSans-SemiBold.ttf -------------------------------------------------------------------------------- /assets/fonts/CalSans-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/assets/fonts/CalSans-SemiBold.woff -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/examples/animeStyle/dbz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/dbz.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/lux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/lux.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/neo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/neo.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/owl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/owl.png -------------------------------------------------------------------------------- /public/images/avatars/shadcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/images/avatars/shadcn.png -------------------------------------------------------------------------------- /public/images/blog/blog-post-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/images/blog/blog-post-1.jpg -------------------------------------------------------------------------------- /public/images/blog/blog-post-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/images/blog/blog-post-2.jpg -------------------------------------------------------------------------------- /public/images/blog/blog-post-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/images/blog/blog-post-3.jpg -------------------------------------------------------------------------------- /public/images/blog/blog-post-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/images/blog/blog-post-4.jpg -------------------------------------------------------------------------------- /assets/fonts/CalSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/assets/fonts/CalSans-SemiBold.woff2 -------------------------------------------------------------------------------- /public/examples/animeStyle/anime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/anime.png -------------------------------------------------------------------------------- /public/examples/animeStyle/levi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/levi.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/ekko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/ekko.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/vayne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/vayne.png -------------------------------------------------------------------------------- /public/examples/shields/shield1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/shields/shield1.png -------------------------------------------------------------------------------- /public/examples/shields/shield2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/shields/shield2.png -------------------------------------------------------------------------------- /public/examples/shields/shield3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/shields/shield3.png -------------------------------------------------------------------------------- /public/examples/shields/shield4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/shields/shield4.png -------------------------------------------------------------------------------- /public/examples/shields/shield5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/shields/shield5.png -------------------------------------------------------------------------------- /public/examples/skillArt/skull1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/skull1.png -------------------------------------------------------------------------------- /public/examples/skillArt/skull2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/skull2.png -------------------------------------------------------------------------------- /public/examples/skillArt/skull3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/skull3.png -------------------------------------------------------------------------------- /public/examples/skillArt/skull4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/skull4.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/anduinn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/anduinn.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/illidan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/illidan.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/thrall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/thrall.png -------------------------------------------------------------------------------- /public/examples/skillArt/frostbolt1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/frostbolt1.png -------------------------------------------------------------------------------- /public/examples/skillArt/frostbolt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/frostbolt2.png -------------------------------------------------------------------------------- /public/examples/skillArt/frostbolt3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/frostbolt3.png -------------------------------------------------------------------------------- /public/examples/skillArt/frostbolt4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/skillArt/frostbolt4.png -------------------------------------------------------------------------------- /public/examples/animeStyle/anime-girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/anime-girl.png -------------------------------------------------------------------------------- /public/examples/animeStyle/fullmetal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/fullmetal.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/deathwing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/deathwing.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/lich-king.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/lich-king.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/scrapyard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/scrapyard.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/warhammer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/warhammer.png -------------------------------------------------------------------------------- /lib/validations/auth.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const userAuthSchema = z.object({ 4 | email: z.string().email(), 5 | }) 6 | -------------------------------------------------------------------------------- /public/examples/animeStyle/anime-boy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/anime-boy-1.png -------------------------------------------------------------------------------- /public/examples/animeStyle/anime-boy-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/anime-boy-2.png -------------------------------------------------------------------------------- /public/examples/animeStyle/fullmetal-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/fullmetal-2.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/tower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/tower.png -------------------------------------------------------------------------------- /public/examples/pixelPortrait/energy-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/pixelPortrait/energy-2.png -------------------------------------------------------------------------------- /public/examples/pixelPortrait/energy-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/pixelPortrait/energy-3.png -------------------------------------------------------------------------------- /public/examples/pixelPortrait/energy-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/pixelPortrait/energy-4.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "singleQuote": false, 5 | "tabWidth": 4, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /lib/validations/user.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const userNameSchema = z.object({ 4 | name: z.string().min(3).max(32), 5 | }) 6 | -------------------------------------------------------------------------------- /public/examples/animeStyle/demon-slayer-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/demon-slayer-1.png -------------------------------------------------------------------------------- /public/examples/animeStyle/demon-slayer-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/demon-slayer-2.png -------------------------------------------------------------------------------- /public/examples/animeStyle/demon-slayer-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/demon-slayer-3.png -------------------------------------------------------------------------------- /public/examples/animeStyle/demon-slayer-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/demon-slayer-4.png -------------------------------------------------------------------------------- /public/examples/animeStyle/hunter-x-hunter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/animeStyle/hunter-x-hunter.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/gothic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/gothic-1.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/gothic-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/gothic-2.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/gothic-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/gothic-3.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/gothic-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/gothic-4.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/horde-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/horde-1.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/horde-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/horde-2.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/horde-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/horde-3.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/horde-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/horde-4.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/farmhouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/farmhouse.png -------------------------------------------------------------------------------- /public/examples/fantasyRpg/anime-cyberpunk-girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/fantasyRpg/anime-cyberpunk-girl.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/bladerunner-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/bladerunner-1.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/bladerunner-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/bladerunner-2.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/bladerunner-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/bladerunner-3.png -------------------------------------------------------------------------------- /public/examples/landscapePortrait/bladerunner-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidTParks/pixelfy/HEAD/public/examples/landscapePortrait/bladerunner-4.png -------------------------------------------------------------------------------- /prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "mysql" -------------------------------------------------------------------------------- /lib/exceptions.ts: -------------------------------------------------------------------------------- 1 | export class RequiresProPlanError extends Error { 2 | constructor(message = "This action requires a pro plan") { 3 | super(message) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/validations/search-generations.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const searchGenerationsSchema = z.object({ 4 | input: z.string().optional(), 5 | }) 6 | -------------------------------------------------------------------------------- /mailing.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript": true, 3 | "emailsDir": "./emails", 4 | "outDir": "./previews_html", 5 | "anonymousId": "809bd078-1867-48f9-9169-9d870291905a" 6 | } 7 | -------------------------------------------------------------------------------- /lib/stripe.ts: -------------------------------------------------------------------------------- 1 | import Stripe from "stripe" 2 | 3 | export const stripe = new Stripe(process.env.STRIPE_API_KEY || "", { 4 | apiVersion: "2022-11-15", 5 | typescript: true, 6 | }) 7 | -------------------------------------------------------------------------------- /lib/validations/generate.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const generateSchema = z.object({ 4 | prompt: z.string().max(500), 5 | modelId: z.string().optional(), 6 | }) 7 | -------------------------------------------------------------------------------- /components/analytics.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { Analytics as VercelAnalytics } from "@vercel/analytics/react" 4 | 5 | export function Analytics() { 6 | return 7 | } 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/validations/og.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const ogImageSchema = z.object({ 4 | heading: z.string(), 5 | type: z.string(), 6 | mode: z.enum(["light", "dark"]).default("dark"), 7 | }) 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /app/(auth)/layout.tsx: -------------------------------------------------------------------------------- 1 | interface AuthLayoutProps { 2 | children: React.ReactNode 3 | } 4 | 5 | export default function AuthLayout({ children }: AuthLayoutProps) { 6 | return
{children}
7 | } 8 | -------------------------------------------------------------------------------- /lib/validations/post.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod" 2 | 3 | export const postPatchSchema = z.object({ 4 | title: z.string().min(3).max(128).optional(), 5 | 6 | // TODO: Type this properly from editorjs block types? 7 | content: z.any().optional(), 8 | }) 9 | -------------------------------------------------------------------------------- /hooks/use-mounted.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | export function useMounted() { 4 | const [mounted, setMounted] = React.useState(false) 5 | 6 | React.useEffect(() => { 7 | setMounted(true) 8 | }, []) 9 | 10 | return mounted 11 | } 12 | -------------------------------------------------------------------------------- /components/session-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { SessionProvider as NextAuthSessionProvider } from "next-auth/react" 4 | 5 | export function SessionProvider({ children }) { 6 | return {children} 7 | } 8 | -------------------------------------------------------------------------------- /lib/session.ts: -------------------------------------------------------------------------------- 1 | import { getServerSession } from "next-auth/next" 2 | 3 | import { authOptions } from "@/lib/auth" 4 | 5 | export async function getCurrentUser() { 6 | const session = await getServerSession(authOptions) 7 | 8 | return session?.user 9 | } 10 | -------------------------------------------------------------------------------- /lib/supabase.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "@supabase/supabase-js" 2 | 3 | const SUPABASE_URL = process.env.SUPABASE_URL as string 4 | const SUPABASE_KEY = process.env.SUPABASE_KEY as string 5 | // Create a single supabase client for interacting with your database 6 | export const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) 7 | -------------------------------------------------------------------------------- /app/robots.ts: -------------------------------------------------------------------------------- 1 | import { MetadataRoute } from "next" 2 | 3 | export default function robots(): MetadataRoute.Robots { 4 | return { 5 | rules: { 6 | userAgent: "*", 7 | allow: "/", 8 | disallow: "/dashboard/", 9 | }, 10 | sitemap: "https://pixelfy.ai/sitemap.xml", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /config/marketing.ts: -------------------------------------------------------------------------------- 1 | import { MarketingConfig } from "types" 2 | 3 | export const marketingConfig: MarketingConfig = { 4 | mainNav: [ 5 | { 6 | title: "Features", 7 | href: "/#features", 8 | }, 9 | { 10 | title: "Examples", 11 | href: "/#examples", 12 | }, 13 | ], 14 | } 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /hooks/use-lock-body.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | // @see https://usehooks.com/useLockBodyScroll. 4 | export function useLockBody() { 5 | React.useLayoutEffect((): (() => void) => { 6 | const originalStyle: string = window.getComputedStyle( 7 | document.body 8 | ).overflow 9 | document.body.style.overflow = "hidden" 10 | return () => (document.body.style.overflow = originalStyle) 11 | }, []) 12 | } 13 | -------------------------------------------------------------------------------- /components/pixelated-image.tsx: -------------------------------------------------------------------------------- 1 | import { pixelateImage } from "@/lib/utils" 2 | import Image, { ImageProps } from "next/image" 3 | 4 | type TPixelatedImageProps = ImageProps & { 5 | src: string 6 | } 7 | export async function PixelatedImage(props: TPixelatedImageProps) { 8 | const pixelatedImage = await pixelateImage({ remoteUrl: props.src }) 9 | 10 | return test 11 | } 12 | -------------------------------------------------------------------------------- /types/next-auth.d.ts: -------------------------------------------------------------------------------- 1 | import { User } from "next-auth" 2 | import { JWT } from "next-auth/jwt" 3 | 4 | type UserId = string 5 | 6 | declare module "next-auth/jwt" { 7 | interface JWT { 8 | id: UserId 9 | credits: number 10 | } 11 | } 12 | 13 | declare module "next-auth" { 14 | interface Session { 15 | user: User & { 16 | id: UserId 17 | credits: number 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /components/shell.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | interface DashboardShellProps extends React.HTMLAttributes {} 6 | 7 | export function DashboardShell({ 8 | children, 9 | className, 10 | ...props 11 | }: DashboardShellProps) { 12 | return ( 13 |
14 | {children} 15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /lib/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client" 2 | 3 | declare global { 4 | // eslint-disable-next-line no-var 5 | var cachedPrisma: PrismaClient 6 | } 7 | 8 | let prisma: PrismaClient 9 | if (process.env.NODE_ENV === "production") { 10 | prisma = new PrismaClient() 11 | } else { 12 | if (!global.cachedPrisma) { 13 | global.cachedPrisma = new PrismaClient() 14 | } 15 | prisma = global.cachedPrisma 16 | } 17 | 18 | export const db = prisma 19 | -------------------------------------------------------------------------------- /config/subscriptions.ts: -------------------------------------------------------------------------------- 1 | import { SubscriptionPlan } from "types" 2 | 3 | export const freePlan: SubscriptionPlan = { 4 | name: "Free", 5 | description: 6 | "The free plan is limited to 3 posts. Upgrade to the PRO plan for unlimited posts.", 7 | stripePriceId: "", 8 | } 9 | 10 | export const proPlan: SubscriptionPlan = { 11 | name: "PRO", 12 | description: "The PRO plan has unlimited posts.", 13 | stripePriceId: process.env.STRIPE_PRO_MONTHLY_PLAN_ID || "", 14 | } 15 | -------------------------------------------------------------------------------- /emails/previews/Account.tsx: -------------------------------------------------------------------------------- 1 | import { default as LoginLinkEmail } from "../LoginLink" 2 | import { default as WelcomeEmailChild } from "../WelcomeEmail" 3 | 4 | export function LoginLink() { 5 | return ( 6 | 7 | ) 8 | } 9 | 10 | export function WelcomeEmail() { 11 | return 12 | } 13 | -------------------------------------------------------------------------------- /components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { SessionProvider } from "./session-provider" 4 | import { ThemeProvider as NextThemesProvider } from "next-themes" 5 | import { ThemeProviderProps } from "next-themes/dist/types" 6 | import * as React from "react" 7 | 8 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 9 | return ( 10 | 11 | {children} 12 | 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /config/site.ts: -------------------------------------------------------------------------------- 1 | import { SiteConfig } from "types" 2 | 3 | export const siteConfig: SiteConfig = { 4 | name: "Pixelfy", 5 | description: 6 | "Pixelfy is an AI-powered application that generates stunning pixel art images. Create unique pixel art with our artificial intelligence tool.", 7 | url: "https://pixelfy.ai", 8 | ogImage: "https://pixelfy.ai/pixelfy-og.png", 9 | links: { 10 | twitter: "https://twitter.com/dparksdev", 11 | github: "https://github.com/DavidTParks/pixelfy", 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | images: { 5 | domains: [ 6 | "avatars.githubusercontent.com", 7 | "cdn.cloud.scenario.com", 8 | "jpxwqgklwwytoznbpbmn.supabase.co", 9 | "lh3.googleusercontent.com" 10 | ], 11 | }, 12 | experimental: { 13 | appDir: true, 14 | serverComponentsExternalPackages: ["@prisma/client"], 15 | }, 16 | } 17 | 18 | export default nextConfig 19 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pixelfy", 3 | "short_name": "Pixelfy", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /emails/components/theme.ts: -------------------------------------------------------------------------------- 1 | // Colors 2 | export const black = "#030711" 3 | export const white = "#fff" 4 | export const purple = "#bd11e0" 5 | export const blue = "#2563EB" 6 | export const gold = "#fadf98" 7 | export const grayDark = "#888" 8 | export const grayLight = "#eaeaea" 9 | 10 | // Typography 11 | export const textSm = 14 12 | export const textBase = 16 13 | export const textLg = 24 14 | export const textXl = 30 15 | export const leadingTight = "120%" 16 | export const leadingRelaxed = "160%" 17 | 18 | // Borders 19 | export const borderBase = 6 20 | -------------------------------------------------------------------------------- /components/card-skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card" 2 | import { Skeleton } from "@/components/ui/skeleton" 3 | 4 | export function CardSkeleton() { 5 | return ( 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /.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 | .env 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | .vscode 40 | .contentlayer 41 | .mailing 42 | -------------------------------------------------------------------------------- /app/(dashboard)/dashboard/loading.tsx: -------------------------------------------------------------------------------- 1 | import { CardSkeleton } from "@/components/card-skeleton" 2 | import { DashboardHeader } from "@/components/header" 3 | import { DashboardShell } from "@/components/shell" 4 | 5 | export default function DashboardSettingsLoading() { 6 | return ( 7 | 8 | 12 |
13 | 14 |
15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /config/docs.ts: -------------------------------------------------------------------------------- 1 | import { scenarioModelData } from "@/lib/generators" 2 | import { DocsConfig } from "types" 3 | 4 | const sideBarExamples = Object.values(scenarioModelData).map( 5 | ({ slug, name, examples }) => ({ 6 | title: name, 7 | href: `/examples/${slug}`, 8 | }) 9 | ) 10 | 11 | export const docsConfig: DocsConfig = { 12 | mainNav: [ 13 | { 14 | title: "Create", 15 | href: "/dashboard", 16 | }, 17 | ], 18 | sidebarNav: [ 19 | { 20 | title: "Styles", 21 | items: sideBarExamples, 22 | }, 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /components/login-button.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { buttonVariants } from "./ui/button" 4 | import { cn } from "@/lib/utils" 5 | import { useSession } from "next-auth/react" 6 | import Link from "next/link" 7 | 8 | export function LoginButton() { 9 | const { status } = useSession() 10 | return ( 11 | 18 | {status === "authenticated" ? "Dashboard" : "Login"} 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /emails/components/Text.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { MjmlText } from "mjml-react" 3 | 4 | type TextProps = { 5 | maxWidth?: number 6 | } & React.ComponentProps 7 | 8 | export default function Text({ children, maxWidth, ...props }: TextProps) { 9 | if (maxWidth) { 10 | return ( 11 | 12 |
{children}
13 |
14 | ) 15 | } else 16 | return ( 17 | 18 | {children} 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /app/(dashboard)/dashboard/refer-users/loading.tsx: -------------------------------------------------------------------------------- 1 | import { CardSkeleton } from "@/components/card-skeleton" 2 | import { DashboardHeader } from "@/components/header" 3 | import { DashboardShell } from "@/components/shell" 4 | 5 | export default function DashboardSettingsLoading() { 6 | return ( 7 | 8 | 12 |
13 | 14 |
15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /components/page-header.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | interface DocsPageHeaderProps extends React.HTMLAttributes { 4 | heading: string 5 | text?: string 6 | } 7 | 8 | export function DocsPageHeader({ 9 | heading, 10 | text, 11 | className, 12 | ...props 13 | }: DocsPageHeaderProps) { 14 | return ( 15 | <> 16 |
17 |

18 | {heading} 19 |

20 | {text &&

{text}

} 21 |
22 |
23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /lib/client-helpers.ts: -------------------------------------------------------------------------------- 1 | import va from "@vercel/analytics" 2 | 3 | export async function downloadImage(url: string, imageName: string) { 4 | va.track("downloadImageSelected", { 5 | url, 6 | imageName, 7 | }) 8 | const a = document.createElement("a") 9 | a.href = await toDataURL(url) 10 | a.download = imageName 11 | document.body.appendChild(a) 12 | a.click() 13 | document.body.removeChild(a) 14 | } 15 | 16 | export function toDataURL(url: string) { 17 | return fetch(url) 18 | .then((response) => { 19 | return response.blob() 20 | }) 21 | .then((blob) => { 22 | return URL.createObjectURL(blob) 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /components/callout.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | interface CalloutProps { 4 | icon?: string 5 | children?: React.ReactNode 6 | type?: "default" | "warning" | "danger" 7 | } 8 | 9 | export function Callout({ 10 | children, 11 | icon, 12 | type = "default", 13 | ...props 14 | }: CalloutProps) { 15 | return ( 16 |
23 | {icon && {icon}} 24 |
{children}
25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /components/header.tsx: -------------------------------------------------------------------------------- 1 | interface DashboardHeaderProps { 2 | heading: string 3 | text?: string 4 | children?: React.ReactNode 5 | } 6 | 7 | export function DashboardHeader({ 8 | heading, 9 | text, 10 | children, 11 | }: DashboardHeaderProps) { 12 | return ( 13 |
14 |
15 |

{heading}

16 | {text && ( 17 |

{text}

18 | )} 19 |
20 | {children} 21 |
22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /lib/upstash.ts: -------------------------------------------------------------------------------- 1 | import { Ratelimit } from "@upstash/ratelimit" 2 | import { Redis } from "@upstash/redis" 3 | 4 | const redisRestUrl = process.env.UPSTASH_REDIS_REST_URL as string 5 | const redisToken = process.env.UPSTASH_REDIS_REST_TOKEN as string 6 | 7 | export const redis = new Redis({ 8 | url: redisRestUrl, 9 | token: redisToken, 10 | }) 11 | 12 | export const ratelimit = ( 13 | requests: number = 10, 14 | seconds: 15 | | `${number} ms` 16 | | `${number} s` 17 | | `${number} m` 18 | | `${number} h` 19 | | `${number} d` = "10 s" 20 | ) => { 21 | return new Ratelimit({ 22 | redis: redis, 23 | limiter: Ratelimit.slidingWindow(requests, seconds), 24 | analytics: true, 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /pages/api/cron/index.ts: -------------------------------------------------------------------------------- 1 | import { db } from "@/lib/db" 2 | import { verifySignature } from "@upstash/qstash/nextjs" 3 | 4 | async function handler(req, res) { 5 | const fifteenMinutesAgo = new Date(Date.now() - 1000 * 60 * 15) 6 | 7 | // Update generations as timed out if 15 minutes have passed 8 | await db.generation.updateMany({ 9 | where: { 10 | createdAt: { 11 | lte: fifteenMinutesAgo, 12 | }, 13 | status: "PROCESSING", 14 | }, 15 | data: { 16 | status: "TIMEOUT", 17 | }, 18 | }) 19 | 20 | res.status(200).end() 21 | } 22 | 23 | export default verifySignature(handler) 24 | 25 | export const config = { 26 | api: { 27 | bodyParser: false, 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /components/user-avatar.tsx: -------------------------------------------------------------------------------- 1 | import { User } from "@prisma/client" 2 | import { AvatarProps } from "@radix-ui/react-avatar" 3 | 4 | import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" 5 | import { Icons } from "@/components/icons" 6 | 7 | interface UserAvatarProps extends AvatarProps { 8 | user: Pick 9 | } 10 | 11 | export function UserAvatar({ user, ...props }: UserAvatarProps) { 12 | return ( 13 | 14 | {user.image ? ( 15 | 16 | ) : ( 17 | 18 | {user.name} 19 | 20 | 21 | )} 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /components/download-image-button.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { Icons } from "@/components/icons" 4 | import { Button } from "@/components/ui/button" 5 | import { downloadImage } from "@/lib/client-helpers" 6 | 7 | interface IDownloadImageButton { 8 | src: string 9 | name: string 10 | } 11 | export const DownloadImageButton = ({ src, name }: IDownloadImageButton) => { 12 | return ( 13 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /emails/components/Divider.tsx: -------------------------------------------------------------------------------- 1 | import { MjmlDivider } from "mjml-react" 2 | import { grayDark, grayLight } from "./theme" 3 | 4 | export default function Divider({ 5 | bottomPadding, 6 | }: { 7 | bottomPadding?: boolean 8 | }): JSX.Element { 9 | return ( 10 | <> 11 | 17 | 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /emails/components/Header.tsx: -------------------------------------------------------------------------------- 1 | import { MjmlColumn, MjmlImage, MjmlSection, MjmlText } from "mjml-react" 2 | 3 | export default function Header({ title }: { title: string }): JSX.Element { 4 | return ( 5 | 6 | 7 | 15 | 16 | {title} 17 | 18 | 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /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 { VariantProps, cva } 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 | -------------------------------------------------------------------------------- /app/i/[id]/loading.tsx: -------------------------------------------------------------------------------- 1 | import { DashboardShell } from "@/components/shell" 2 | import { AspectRatio } from "@/components/ui/aspect-ratio" 3 | import { Skeleton } from "@/components/ui/skeleton" 4 | 5 | export default function LoadingImage() { 6 | return ( 7 | 8 |
9 |
10 | 11 | 12 | 13 |
14 |
15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /components/carbon.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useEffect, useRef } from "react" 4 | 5 | export const Carbon = () => { 6 | useEffect(() => { 7 | const script = document.createElement("script") 8 | const carbonContainer = document.getElementById("carbon-container") 9 | script.setAttribute("async", "true") 10 | script.setAttribute( 11 | "src", 12 | "//cdn.carbonads.com/carbon.js?serve=CWYDP5QM&placement=wwwpixelfyai" 13 | ) 14 | script.setAttribute("id", "_carbonads_js") 15 | 16 | if (carbonContainer) { 17 | carbonContainer.appendChild(script) 18 | } 19 | 20 | return () => { 21 | if (carbonContainer) { 22 | carbonContainer.removeChild(script) 23 | } 24 | } 25 | }, []) 26 | return null 27 | } 28 | -------------------------------------------------------------------------------- /components/modal.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { Dialog, DialogContent, DialogFooter } from "@/components/ui/dialog" 4 | import { useRouter } from "next/navigation" 5 | 6 | interface IModal { 7 | footer: React.ReactNode 8 | children: React.ReactNode 9 | } 10 | export default function Modal({ children, footer }: IModal) { 11 | const router = useRouter() 12 | 13 | const handleOnOpenChange = (open: boolean) => { 14 | if (!open) { 15 | router.back() 16 | } 17 | } 18 | return ( 19 | 20 | 21 |
{children}
22 | {footer} 23 |
24 |
25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/eslintrc", 3 | "root": true, 4 | "extends": [ 5 | "next/core-web-vitals", 6 | "prettier", 7 | "plugin:tailwindcss/recommended" 8 | ], 9 | "plugins": ["tailwindcss"], 10 | "rules": { 11 | "@next/next/no-html-link-for-pages": "off", 12 | "react/jsx-key": "off", 13 | "tailwindcss/no-custom-classname": "off", 14 | "tailwindcss/classnames-order": "off", 15 | "react/no-unescaped-entities": "off" 16 | }, 17 | "settings": { 18 | "tailwindcss": { 19 | "callees": ["cn"], 20 | "config": "tailwind.config.js" 21 | }, 22 | "next": { 23 | "rootDir": true 24 | } 25 | }, 26 | "overrides": [ 27 | { 28 | "files": ["*.ts", "*.tsx"], 29 | "parser": "@typescript-eslint/parser" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | import * as React from "react" 3 | 4 | export interface TextareaProps 5 | extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |