├── hooks ├── api-keys-hooks.ts ├── index-fxns.ts ├── use-templates.tsx ├── use-undo-redo.tsx └── use-toast.ts ├── vercel.json ├── .eslintrc.json ├── postcss.config.js ├── .npmrc ├── lib ├── utils.ts ├── uploadthing.ts ├── db.ts ├── auth-client.ts ├── auth-utils.ts ├── auth.ts ├── local-storage.ts ├── github.ts ├── certificates.ts ├── firebase-storage.ts └── local-upload.ts ├── app ├── (auth) │ ├── sign-in │ │ └── page.tsx │ ├── sign-up │ │ └── page.tsx │ └── layout.tsx ├── api │ ├── auth │ │ └── [...all] │ │ │ └── route.ts │ ├── uploadthing │ │ ├── route.ts │ │ └── core.ts │ ├── github-stats │ │ └── route.ts │ ├── track │ │ ├── enhancement │ │ │ └── route.ts │ │ └── watermark │ │ │ └── route.ts │ └── stats │ │ └── route.ts ├── watermark │ └── page.tsx ├── page.tsx ├── layout.tsx ├── pricing │ └── layout.tsx └── globals.css ├── components ├── ui │ ├── aspect-ratio.tsx │ ├── skeleton.tsx │ ├── collapsible.tsx │ ├── label.tsx │ ├── textarea.tsx │ ├── separator.tsx │ ├── progress.tsx │ ├── toaster.tsx │ ├── input.tsx │ ├── dotted-background.tsx │ ├── sonner.tsx │ ├── checkbox.tsx │ ├── slider.tsx │ ├── switch.tsx │ ├── badge.tsx │ ├── tooltip.tsx │ ├── hover-card.tsx │ ├── popover.tsx │ ├── avatar.tsx │ ├── toggle.tsx │ ├── radio-group.tsx │ ├── alert.tsx │ ├── scroll-area.tsx │ ├── resizable.tsx │ ├── toggle-group.tsx │ ├── button.tsx │ ├── tabs.tsx │ ├── accordion.tsx │ ├── card.tsx │ ├── modal.tsx │ ├── input-otp.tsx │ ├── calendar.tsx │ ├── breadcrumb.tsx │ ├── pagination.tsx │ ├── table.tsx │ ├── drawer.tsx │ ├── github-star-button.tsx │ ├── dialog.tsx │ ├── image-comparison-slider.tsx │ ├── sheet.tsx │ ├── form.tsx │ ├── alert-dialog.tsx │ ├── toast.tsx │ └── navigation-menu.tsx ├── theme-provider.tsx ├── mode-toggle.tsx ├── settings │ ├── input-with-icon.tsx │ ├── notification-settings.tsx │ ├── profile-form.tsx │ ├── security-settings.tsx │ └── api-keys.tsx ├── certificates │ ├── editor │ │ ├── field-type-selector.tsx │ │ ├── field-list.tsx │ │ └── field-inspector.tsx │ ├── certificate-templates.tsx │ ├── template-uploader.tsx │ ├── certificate-generator.tsx │ ├── template-list.tsx │ └── template-editor.tsx ├── auth │ └── auth-button.tsx ├── landing │ ├── features.tsx │ └── footer.tsx └── backend-status.tsx ├── utils └── uploadthing.ts ├── middleware.ts ├── components.json ├── tsconfig.json ├── .gitignore ├── .env.example ├── next.config.js ├── LICENSE ├── README.md ├── scripts └── deploy.sh ├── VERCEL-ENV-SETUP.md ├── tailwind.config.ts ├── prisma └── schema.prisma └── package.json /hooks/api-keys-hooks.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "regions": ["iad1"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Force npm usage and disable other package managers 2 | engine-strict=true 3 | save-exact=false 4 | fund=false 5 | audit=false 6 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /app/(auth)/sign-in/page.tsx: -------------------------------------------------------------------------------- 1 | import { InnovativeAuthPage } from "@/components/auth/innovative-auth-page"; 2 | 3 | export default function SignInPage() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /app/(auth)/sign-up/page.tsx: -------------------------------------------------------------------------------- 1 | import { InnovativeAuthPage } from "@/components/auth/innovative-auth-page"; 2 | 3 | export default function SignUpPage() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /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/uploadthing.ts: -------------------------------------------------------------------------------- 1 | import { generateReactHelpers } from "@uploadthing/react"; 2 | import type { OurFileRouter } from "@/app/api/uploadthing/core"; 3 | 4 | export const { useUploadThing, uploadFiles } = generateReactHelpers(); 5 | -------------------------------------------------------------------------------- /app/api/auth/[...all]/route.ts: -------------------------------------------------------------------------------- 1 | import { auth } from "@/lib/auth" 2 | 3 | export async function GET(request: Request) { 4 | return auth.handler(request) 5 | } 6 | 7 | export async function POST(request: Request) { 8 | return auth.handler(request) 9 | } 10 | -------------------------------------------------------------------------------- /app/api/uploadthing/route.ts: -------------------------------------------------------------------------------- 1 | import { createRouteHandler } from "uploadthing/next"; 2 | 3 | import { ourFileRouter } from "./core"; 4 | 5 | // Export routes for Next App Router 6 | export const { GET, POST } = createRouteHandler({ 7 | router: ourFileRouter, 8 | 9 | // Apply an (optional) custom config: 10 | // config: { ... }, 11 | }); -------------------------------------------------------------------------------- /utils/uploadthing.ts: -------------------------------------------------------------------------------- 1 | import { 2 | generateUploadButton, 3 | generateUploadDropzone, 4 | } from "@uploadthing/react"; 5 | 6 | import type { OurFileRouter } from "@/app/api/uploadthing/core"; 7 | export const UploadButton = generateUploadButton(); 8 | export const UploadDropzone = generateUploadDropzone(); 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client' 2 | 3 | const globalForPrisma = globalThis as unknown as { 4 | prisma: PrismaClient | undefined 5 | } 6 | 7 | export const db = 8 | globalForPrisma.prisma ?? 9 | new PrismaClient({ 10 | log: ['query'], 11 | }) 12 | 13 | if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db 14 | -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | 3 | export function middleware(request: NextRequest) { 4 | // For now, allow all requests - Better Auth handles its own middleware 5 | return NextResponse.next(); 6 | } 7 | 8 | export const config = { 9 | matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"], 10 | }; 11 | -------------------------------------------------------------------------------- /components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | import { type ThemeProviderProps } from "next-themes/dist/types"; 6 | 7 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 8 | return {children}; 9 | } -------------------------------------------------------------------------------- /app/watermark/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Navbar } from "@/components/navbar"; 4 | 5 | export default function WatermarkPage() { 6 | return ( 7 | <> 8 | 9 |
10 |

AI Watermarking - Coming Soon!

11 |
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 | -------------------------------------------------------------------------------- /app/(auth)/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from "@/components/navbar"; 2 | import { Footer } from "@/components/landing/footer"; 3 | 4 | export default function AuthLayout({ 5 | children, 6 | }: { 7 | children: React.ReactNode; 8 | }) { 9 | return ( 10 |
11 | 12 |
13 | {children} 14 |
15 |
16 |
17 | ); 18 | } -------------------------------------------------------------------------------- /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": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/auth-client.ts: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | 4 | import { createAuthClient } from "better-auth/react" 5 | 6 | 7 | export const authClient = createAuthClient({ 8 | baseURL: process.env.NEXT_PUBLIC_APP_URL || ( 9 | process.env.NODE_ENV === 'production' 10 | ? 'https://pixelfly-pi.vercel.app' 11 | : 'http://localhost:3000' 12 | ), 13 | }) 14 | 15 | export const { 16 | signIn, 17 | signUp, 18 | signOut, 19 | useSession, 20 | getSession, 21 | } = authClient 22 | 23 | // to fixed some buggy code here later on. -------------------------------------------------------------------------------- /hooks/index-fxns.ts: -------------------------------------------------------------------------------- 1 | 2 | // import axios from 'axios' 3 | // entirely comment all these pages. 4 | 5 | // export const GenerateCertificate = asnyc() => { 6 | // try { 7 | 8 | // const request = await axios.post('api/certificates/generate', { 9 | 10 | // }) 11 | 12 | // if (request.status === 200){ 13 | 14 | // return request.data 15 | 16 | // } 17 | // return null 18 | // } catch (eror:any) { 19 | 20 | // console.log(eror.message) 21 | // return null 22 | 23 | // } 24 | // } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | # lockfiles (we use npm, not pnpm/yarn) 9 | pnpm-lock.yaml 10 | yarn.lock 11 | 12 | # testing 13 | /coverage 14 | 15 | # next.js 16 | /.next/ 17 | /out/ 18 | 19 | # production 20 | /build 21 | 22 | # misc 23 | .DS_Store 24 | *.pem 25 | 26 | # environment variables 27 | .env 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | *.env 33 | 34 | # debug 35 | npm-debug.log* 36 | yarn-debug.log* 37 | yarn-error.log* 38 | 39 | # vercel 40 | .vercel 41 | 42 | # typescript 43 | *.tsbuildinfo 44 | next-env.d.ts 45 | 46 | /lib/generated/prisma 47 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from "@/components/navbar"; 2 | import { LandingHero } from "@/components/landing/hero"; 3 | import { LandingStats } from "@/components/landing/stats"; 4 | import { BeforeAfterShowcase } from "@/components/landing/before-after-showcase"; 5 | import { InteractiveDemo } from "@/components/landing/interactive-demo"; 6 | import { Features } from "@/components/landing/features"; 7 | import { Footer } from "@/components/landing/footer"; 8 | 9 | export default function Home() { 10 | return ( 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /components/mode-toggle.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Moon, Sun } from "lucide-react"; 4 | import { useTheme } from "next-themes"; 5 | import { Button } from "@/components/ui/button"; 6 | 7 | export function ModeToggle() { 8 | const { theme, setTheme } = useTheme(); 9 | // did nnot know there was a theme here ohh 10 | 11 | return ( 12 | 21 | ); 22 | } -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Database 2 | DATABASE_URL="mongodb+srv://username:password@cluster.mongodb.net/database" 3 | 4 | # Better Auth Configuration 5 | BETTER_AUTH_SECRET="your-super-secret-key-change-this-in-production" 6 | BETTER_AUTH_URL="http://localhost:3001" 7 | NEXT_PUBLIC_APP_URL="http://localhost:3001" 8 | 9 | # Google OAuth (Get these from Google Cloud Console) 10 | GOOGLE_CLIENT_ID="your-google-client-id" 11 | GOOGLE_CLIENT_SECRET="your-google-client-secret" 12 | 13 | # UploadThing (Optional - for file uploads) 14 | UPLOADTHING_TOKEN="your-uploadthing-token" 15 | 16 | # Backend API Configuration 17 | NEXT_PUBLIC_BACKEND_URL="http://localhost:5001" 18 | # For Vercel deployment, set to your Vercel app URL: 19 | # NEXT_PUBLIC_BACKEND_URL="https://your-app.vercel.app" 20 | 21 | # GitHub API (for repository stats) 22 | GITHUB_TOKEN="your-github-token" 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/lib/utils'; 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |