├── .env.example ├── .eslintignore ├── .eslintrc.cjs ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── README.md ├── en.json ├── package-lock.json ├── package.json ├── postcss.config.cjs ├── src ├── app.css ├── app.d.ts ├── app.html ├── hooks.client.ts ├── hooks.server.ts ├── i18n.d.ts ├── lib │ ├── components │ │ ├── Alert.svelte │ │ ├── Button.svelte │ │ ├── Icon.svelte │ │ ├── Input.svelte │ │ ├── MessagesQueue.svelte │ │ ├── Modal.svelte │ │ ├── Title.svelte │ │ ├── Tooltip.svelte │ │ └── svg │ │ │ ├── GitHub.svelte │ │ │ ├── Google.svelte │ │ │ ├── Instagram.svelte │ │ │ ├── TikTok.svelte │ │ │ └── Twitter.svelte │ ├── db.server.ts │ ├── db.ts │ ├── i18n.ts │ ├── icon-types.ts │ ├── layout │ │ ├── Footer.svelte │ │ ├── Header.svelte │ │ └── Hero.svelte │ ├── locales │ │ ├── en.ts │ │ └── it.ts │ ├── predictions.server.ts │ ├── prompts.server.ts │ ├── replicate.server.ts │ ├── supabase-types.ts │ ├── themes.ts │ └── utilities.ts └── routes │ ├── (app) │ ├── +layout.svelte │ ├── +layout.ts │ └── app │ │ ├── +page.svelte │ │ └── +page.ts │ ├── (homepage) │ ├── +layout.server.ts │ ├── +layout.svelte │ ├── +layout.ts │ ├── +page.svelte │ ├── TextGradient.svelte │ ├── checkout │ │ └── +server.ts │ ├── contacts │ │ └── +page.svelte │ ├── login │ │ ├── +page.svelte │ │ └── +page.ts │ ├── logout │ │ ├── +page.svelte │ │ └── +page.ts │ └── payment_success │ │ ├── +page.svelte │ │ └── +page.ts │ ├── _about │ └── +page.svelte │ ├── _help │ └── +page.svelte │ ├── _legal │ └── terms-and-conditions │ │ └── +page.svelte │ ├── _signup │ ├── +page.svelte │ └── +page.ts │ └── api │ ├── prediction │ ├── +server.ts │ └── prediction.test.ts │ ├── train │ └── +server.ts │ └── webhooks │ ├── [slug] │ ├── instance_data │ │ └── +server.ts │ ├── prediction_complete │ │ └── +server.ts │ └── training_complete │ │ └── +server.ts │ └── payment │ └── +server.ts ├── static ├── american-express.svg ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-pay.svg ├── apple-touch-icon.png ├── arrow.svg ├── avatars │ ├── man (1).jpeg │ ├── man (10).jpeg │ ├── man (2).jpeg │ ├── man (3).jpeg │ ├── man (4).jpeg │ ├── man (5).jpeg │ ├── man (6).jpeg │ ├── man (7).jpeg │ ├── man (8).jpeg │ ├── man (9).jpeg │ ├── man_from.jpg │ ├── woman (1).jpeg │ ├── woman (10).jpeg │ ├── woman (11).jpeg │ ├── woman (12).jpeg │ ├── woman (2).jpeg │ ├── woman (3).jpeg │ ├── woman (4).jpeg │ ├── woman (5).jpeg │ ├── woman (6).jpeg │ ├── woman (7).jpeg │ ├── woman (8).jpeg │ ├── woman (9).jpeg │ └── woman_from.jpg ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── google-pay.svg ├── logo-xs.png ├── logo.png ├── mastercard-alt.svg ├── og.jpg ├── site.webmanifest └── visa.svg ├── supabase ├── .gitignore ├── .vscode │ └── settings.json ├── config.toml └── seed.sql ├── svelte.config.js ├── tailwind.config.cjs ├── tsconfig.json ├── vite.config.js └── vitest.config.js /.env.example: -------------------------------------------------------------------------------- 1 | # Supabase 2 | PUBLIC_SUPABASE_URL= 3 | PUBLIC_SUPABASE_KEY= 4 | PRIVATE_SUPABASE_SERVICE_ROLE= 5 | 6 | # Stripe 7 | PUBLIC_STRIPE_PRICE_ID= 8 | PUBLIC_ENV= 9 | PRIVATE_STRIPE_API_KEY= 10 | PRIVATE_STRIPE_ENDPOINT_SECRET= 11 | 12 | 13 | # Replicate 14 | PRIVATE_REPLICATE_INSTANCE_TOKEN= 15 | PRIVATE_REPLICATE_API_TOKEN= 16 | PRIVATE_REPLICATE_MAX_TRAIN_STEPS= 17 | PRIVATE_REPLICATE_USERNAME= 18 | 19 | # Web 20 | PUBLIC_ENV= 21 | PUBLIC_WEBSITE_HOST= -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], 5 | rules: { 6 | camelcase: ['error', { properties: 'never' }] 7 | }, 8 | plugins: ['svelte3', '@typescript-eslint'], 9 | ignorePatterns: ['*.cjs'], 10 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 11 | settings: { 12 | 'svelte3/typescript': () => require('typescript') 13 | }, 14 | parserOptions: { 15 | sourceType: 'module', 16 | ecmaVersion: 2020 17 | }, 18 | env: { 19 | browser: true, 20 | es2017: true, 21 | node: true 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | .vercel -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100, 6 | "plugins": ["prettier-plugin-svelte"], 7 | "pluginSearchDirs": ["."], 8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["svelte.svelte-vscode", "bradlc.vscode-tailwindcss", "esbenp.prettier-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Launch via NPM", 5 | "request": "launch", 6 | "runtimeArgs": ["run-script", "dev"], 7 | "runtimeExecutable": "npm", 8 | "skipFiles": ["/**"], 9 | "type": "node" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "eslint.validate": ["svelte"] 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Avatarify AI 2 | A platform for creating personal AI models for your profile picture 3 | 4 | ## Technologies used 5 | - 💅🏽 Frontend: Svelte and TypeScript in strict mode with TailwindCSS and DaisyUI components 6 | - 🪄 Backend: Supabase for authentication, user data and photo storage 7 | - 🚄 Server: Vercel for deployment with SSR, SSG, and serverless endpoints 8 | - 💲 Payments: Stripe integration for payments 9 | - 🧙🏽‍♂️ Training API: Replicate for REST services for training and photo generation 10 | 11 | ## Getting started 12 | 1. Clone the repository: `https://github.com/epavanello/avatarify-ai.com` 13 | 2. Install the dependencies: `npm install` 14 | 3. Start the development server: `npm run dev` 15 | 16 | ## Contributing 17 | We welcome contributions of any kind, including bug reports, feature requests, and pull requests. If you're interested in contributing, please take a look at our open issues. 18 | 19 | ## License 20 | This project is licensed under the MIT license. 21 | -------------------------------------------------------------------------------- /en.json: -------------------------------------------------------------------------------- 1 | { 2 | "claim": "Unleash the power of AI on your images. Simple, unique, professional." 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avatarify-ai.com", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite dev --open", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 10 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 11 | "lint": "prettier --plugin-search-dir . --check . && eslint .", 12 | "format": "prettier --plugin-search-dir . --write .", 13 | "generate-supabase-types": "supabase gen types typescript --linked > src/lib/supabase-types.ts", 14 | "test": "cross-env TEST=true vitest" 15 | }, 16 | "devDependencies": { 17 | "@sveltejs/adapter-auto": "^1.0.0", 18 | "@sveltejs/kit": "^1.0.0", 19 | "@typescript-eslint/eslint-plugin": "^5.45.0", 20 | "@typescript-eslint/parser": "^5.45.0", 21 | "autoprefixer": "^10.4.13", 22 | "eslint": "^8.28.0", 23 | "eslint-config-prettier": "^8.5.0", 24 | "eslint-plugin-svelte3": "^4.0.0", 25 | "jsdom": "^21.1.0", 26 | "postcss": "^8.4.20", 27 | "prettier": "^2.8.0", 28 | "prettier-plugin-svelte": "^2.8.1", 29 | "supabase": "^1.33.0", 30 | "svelte": "^3.54.0", 31 | "svelte-check": "^2.9.2", 32 | "tailwindcss": "^3.2.4", 33 | "tslib": "^2.4.1", 34 | "typescript": "^4.9.3", 35 | "vite": "^4.0.0" 36 | }, 37 | "type": "module", 38 | "dependencies": { 39 | "@cloudamqp/amqp-client": "^2.1.1", 40 | "@stripe/stripe-js": "^1.46.0", 41 | "@supabase/auth-helpers-sveltekit": "^0.8.6", 42 | "@supabase/supabase-js": "^2.4.0", 43 | "@sveltejs/adapter-vercel": "^1.0.0", 44 | "@tailwindcss/typography": "^0.5.8", 45 | "aws-sdk": "^2.1290.0", 46 | "classnames": "^2.3.2", 47 | "compressorjs": "^1.1.1", 48 | "cross-env": "^7.0.3", 49 | "daisyui": "^2.46.0", 50 | "dotenv": "^16.0.3", 51 | "i18next": "^22.4.9", 52 | "i18next-browser-languagedetector": "^7.0.1", 53 | "jszip": "^3.10.1", 54 | "stripe": "^11.6.0", 55 | "svelte-i18next": "^1.2.2", 56 | "vitest": "^0.28.2", 57 | "watermarkjs": "^2.1.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .text-gradient { 6 | @apply text-transparent bg-clip-text bg-gradient-to-r from-green-400 to-blue-500; 7 | } 8 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | // and what to do when importing types 4 | declare namespace App { 5 | interface Supabase { 6 | Database: import('./lib/supabase-types').Database; 7 | SchemaName: 'public'; 8 | } 9 | 10 | // interface Locals {} 11 | interface PageData { 12 | session: import('@supabase/supabase-js').Session | null; 13 | } 14 | // interface Error {} 15 | // interface Platform {} 16 | } 17 | declare module 'watermarkjs' { 18 | function Watermark(images: string[], options: any): any; 19 | namespace Watermark { 20 | const image: any; 21 | } // This is a hack to allow ES6 wildcard imports 22 | export = Watermark; 23 | } 24 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Avatarify AI 12 | 14 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | %sveltekit.head% 40 | 41 | 42 | 44 | 51 | 58 | 59 | 61 | 62 | 63 | 64 | 69 |
%sveltekit.body%
70 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/hooks.client.ts: -------------------------------------------------------------------------------- 1 | import '$lib/db'; 2 | 3 | // Extend to manage errors https://kit.svelte.dev/docs/hooks#shared-hooks-handleerror 4 | -------------------------------------------------------------------------------- /src/hooks.server.ts: -------------------------------------------------------------------------------- 1 | import '$lib/db'; 2 | 3 | // Extend to manage errors https://kit.svelte.dev/docs/hooks#shared-hooks-handleerror 4 | -------------------------------------------------------------------------------- /src/i18n.d.ts: -------------------------------------------------------------------------------- 1 | // import the original type declarations 2 | import 'i18next'; 3 | // import all namespaces (for the default language, only) 4 | import type en from '$lib/locales/en'; 5 | 6 | declare module 'i18next' { 7 | // Extend CustomTypeOptions 8 | interface CustomTypeOptions { 9 | // custom namespace type, if you changed it 10 | defaultNS: 'common'; 11 | // custom resources type 12 | resources: typeof en; 13 | // other 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/lib/components/Alert.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
16 |
17 | {#if type == 'error'} 18 | error 19 | {:else if type == 'info'} 20 | info 21 | {/if} 22 |
23 | {#if $$slots.title} 24 |

25 | 26 |

27 | {/if} 28 |
29 |
30 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /src/lib/components/Button.svelte: -------------------------------------------------------------------------------- 1 | 27 | 28 | 63 | {#if startIcon} 64 | 65 | {/if} 66 | {#if icon} 67 | 68 | {:else if disco} 69 | 70 | 74 | 75 | 78 | 79 | 80 | 81 | {:else} 82 | 83 | {/if} 84 | {#if endIcon} 85 | 86 | {/if} 87 | 88 | -------------------------------------------------------------------------------- /src/lib/components/Icon.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | {@html `&#x${Icons[name]};`} 17 | 18 | -------------------------------------------------------------------------------- /src/lib/components/Input.svelte: -------------------------------------------------------------------------------- 1 | 29 | 30 |
31 | {#if label} 32 | 35 | {/if} 36 | 37 |
38 | {#if type == 'textarea'} 39 |