├── .eslintrc.json
├── app
├── favicon.ico
├── opengraph-image.png
├── page.tsx
├── api
│ ├── upload
│ │ └── route.ts
│ └── webhook
│ │ └── route.ts
├── sitemap.ts
├── t
│ └── [id]
│ │ ├── page.tsx
│ │ └── opengraph-image.tsx
├── gallery
│ └── page.tsx
└── layout.tsx
├── public
├── logo.png
├── old_2.png
├── github.png
└── old_logo.png
├── styles
├── globals.css
└── ClashDisplay-Semibold.otf
├── postcss.config.js
├── prettier.config.js
├── components
├── icons
│ ├── index.tsx
│ ├── twitter.tsx
│ ├── github.tsx
│ ├── loading-circle.tsx
│ └── buymeacoffee.tsx
├── generated-count.tsx
├── pattern-picker.tsx
├── popover.tsx
├── form-rsc.tsx
├── photo-booth.tsx
└── form.tsx
├── lib
├── constants.ts
├── hooks
│ ├── use-enter-submit.ts
│ └── use-media-query.ts
├── utils.ts
└── actions.ts
├── .env.example
├── .gitignore
├── tsconfig.json
├── next.config.js
├── package.json
├── README.md
├── tailwind.config.ts
└── pnpm-lock.yaml
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/app/favicon.ico
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/public/logo.png
--------------------------------------------------------------------------------
/public/old_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/public/old_2.png
--------------------------------------------------------------------------------
/public/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/public/github.png
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/public/old_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/public/old_logo.png
--------------------------------------------------------------------------------
/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/app/opengraph-image.png
--------------------------------------------------------------------------------
/styles/ClashDisplay-Semibold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/garrrikkotua/octoart/HEAD/styles/ClashDisplay-Semibold.otf
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | // prettier.config.js
2 | module.exports = {
3 | bracketSpacing: true,
4 | semi: true,
5 | trailingComma: "all",
6 | printWidth: 80,
7 | tabWidth: 2,
8 | plugins: ["prettier-plugin-tailwindcss"],
9 | };
10 |
--------------------------------------------------------------------------------
/components/icons/index.tsx:
--------------------------------------------------------------------------------
1 | export { default as Github } from "./github";
2 | export { default as Twitter } from "./twitter";
3 | export { default as LoadingCircle } from "./loading-circle";
4 | export { default as BuyMeACoffee } from "./buymeacoffee";
5 |
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | import FormRSC from "@/components/form-rsc";
2 |
3 | export default function Home() {
4 | return (
5 |
15 | {count ? nFormatter(count) : "..."} photos generated and counting! 16 |
17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | experimental: { 4 | serverActions: true, 5 | }, 6 | images: { 7 | domains: [ 8 | "w3hp0wwfpdgpzwdt.public.blob.vercel-storage.com", 9 | "xd2kcvzsdpeyx1gu.public.blob.vercel-storage.com", 10 | "replicate.delivery", 11 | ], 12 | }, 13 | async redirects() { 14 | return [ 15 | { 16 | source: "/github", 17 | destination: "https://github.com/garrrikkotua/github-illusion", 18 | permanent: false, 19 | }, 20 | 21 | { 22 | source: "/t", 23 | destination: "/", 24 | permanent: false, 25 | }, 26 | ]; 27 | }, 28 | }; 29 | 30 | module.exports = nextConfig; 31 | -------------------------------------------------------------------------------- /app/api/upload/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | import { put } from "@vercel/blob"; 3 | import { kv } from "@vercel/kv"; 4 | import fs from 'fs'; 5 | import path from 'path'; 6 | import { nanoid } from "@/lib/utils"; 7 | 8 | export async function POST(req: Request) { 9 | const body = await req.json(); 10 | const { filePath } = body; 11 | 12 | if (!filePath) { 13 | return new Response("Missing filepath", { status: 400 }); 14 | } 15 | const id = nanoid(); 16 | 17 | // read file from local filesystem 18 | const file = fs.readFileSync(path.resolve(filePath)); 19 | 20 | // upload & store in Vercel Blob 21 | const { url } = await put(`${id}.png`, file, { access: "public" }); 22 | 23 | await kv.hset(id, { image: url }); 24 | 25 | return NextResponse.json({ ok: true, id, url }); 26 | } 27 | -------------------------------------------------------------------------------- /app/sitemap.ts: -------------------------------------------------------------------------------- 1 | import { kv } from "@vercel/kv"; 2 | import { MetadataRoute } from "next"; 3 | 4 | export default async function sitemap(): Promise21 | Choose a pattern 22 |
23 |
3 | 7 | Generate beautiful GitHub octocat art with one click. Promote open-source! 8 |
9 | 10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 | Introduction · 21 | Tech Stack · 22 | Author · 23 | Credits 24 |
25 |26 | 🚀 Generate AI picture with your logo - check out LogoPicture AI 27 |
28 | 29 | ) : ( 30 | 36 |37 | 🚀 Generate AI picture with your logo - check out LogoPicture AI ↣ 38 |
39 | 40 | )} 41 | 42 |52 | Generate beautiful GitHub octocat art with one click. Promote 53 | open-source! 54 |
55 | 56 |84 | A project by{" "} 85 | 91 | Igor Kotua 92 | 93 |
94 |95 | Subscribe to my{" "} 96 | 102 | newsletter 103 | 104 |
105 |126 | This can take anywhere between 20s-30s to run. 127 |
128 |