From d8fb36e6c34a433f290b9d51d180071082e345d1 Mon Sep 17 00:00:00 2001 From: Carlos Date: Mon, 29 Jun 2026 08:26:45 +0200 Subject: [PATCH] feat: initial commit - 1000apps SaaS container --- .env.example | 13 + .gitignore | 5 + Dockerfile | 45 + PERSISTENCE_CONFIRMED.md | 45 + components/AvatarSelector.jsx | 48 + components/CategoryMenu.jsx | 32 + docker-compose.simple.yml | 22 + docker-compose.yml | 44 + jsconfig.json | 5 + lib/prisma.js | 7 + next.config.js | 8 + package-lock.json | 1662 +++++++++++++++++++++++++++++++ package.json | 31 + pages/_app.jsx | 13 + pages/api/auth/[...nextauth].js | 53 + pages/api/auth/signin.js | 54 + pages/api/auth/signup.js | 53 + pages/apps/trendsnews/index.jsx | 224 +++++ pages/dashboard.jsx | 167 ++++ pages/index.jsx | 139 +++ pages/signin.jsx | 85 ++ pages/signup.jsx | 104 ++ postcss.config.js | 6 + prisma/schema.prisma | 34 + public/index.html | 153 +++ scripts/build.sh | 12 + styles/globals.css | 17 + tailwind.config.js | 11 + 28 files changed, 3092 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 PERSISTENCE_CONFIRMED.md create mode 100644 components/AvatarSelector.jsx create mode 100644 components/CategoryMenu.jsx create mode 100644 docker-compose.simple.yml create mode 100644 docker-compose.yml create mode 100644 jsconfig.json create mode 100644 lib/prisma.js create mode 100644 next.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages/_app.jsx create mode 100644 pages/api/auth/[...nextauth].js create mode 100644 pages/api/auth/signin.js create mode 100644 pages/api/auth/signup.js create mode 100644 pages/apps/trendsnews/index.jsx create mode 100644 pages/dashboard.jsx create mode 100644 pages/index.jsx create mode 100644 pages/signin.jsx create mode 100644 pages/signup.jsx create mode 100644 postcss.config.js create mode 100644 prisma/schema.prisma create mode 100644 public/index.html create mode 100644 scripts/build.sh create mode 100644 styles/globals.css create mode 100644 tailwind.config.js diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..27aa701 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +# Environment variables for 1000apps +# Copy this to .env and fill in the values + +# Database +DATABASE_URL=postgresql://user:password@db:5432/1000apps + +# NextAuth +NEXTAUTH_SECRET=CHANGE_THIS_TO_RANDOM_32_CHARS +NEXTAUTH_URL=https://1000apps.fluxtechnologies.uk + +# Google OAuth (optional - for Google login) +GOOGLE_CLIENT_ID=your_google_client_id +GOOGLE_CLIENT_SECRET=your_google_client_secret \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..87bc58a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.next/ +.env +.env.local +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..da75319 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# Multi-stage build for Next.js +FROM node:20-alpine AS base +WORKDIR /app + +# Install dependencies +FROM base AS deps +RUN apk add --no-cache libc6-compat openssl +COPY package.json package-lock.json* ./ +RUN npm install --frozen-lockfile + +# Build stage +FROM base AS builder +WORKDIR /app +ENV DATABASE_URL="postgresql://user:***@localhost:5432/1000apps" +COPY --from=deps /app/node_modules ./node_modules +COPY . . +ENV NEXT_TELEMETRY_DISABLED=1 +RUN npx prisma generate +RUN npm run build + +# Production stage +FROM node:20-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production + +# Install runtime dependencies for Prisma +RUN apk add --no-cache libc6-compat openssl + +# Create non-root user and set permissions +RUN addgroup -g 1001 -S nodejs && \ + adduser -S nextjs -u 1001 -G nodejs + +COPY --from=builder --chown=nextjs:nodejs /app/package.json ./ +COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules +COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next +COPY --from=builder --chown=nextjs:nodejs /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/next.config.js ./ +COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma +COPY --from=builder --chown=nextjs:nodejs /app/pages ./pages +COPY --from=builder --chown=nextjs:nodejs /app/lib ./lib +COPY --from=builder --chown=nextjs:nodejs /app/components ./components +COPY --from=builder --chown=nextjs:nodejs /app/styles ./styles + +EXPOSE 3000 +CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/PERSISTENCE_CONFIRMED.md b/PERSISTENCE_CONFIRMED.md new file mode 100644 index 0000000..a49d9a3 --- /dev/null +++ b/PERSISTENCE_CONFIRMED.md @@ -0,0 +1,45 @@ +# ✅ PostgreSQL Persistence - CONFIRMED + +## Test Date: 2026-06-27 14:10 UTC + +### User Created via API +```json +POST /api/auth/signup +{ + "username": "persistence-test", + "password": "test123" +} + +Response: +{ + "message": "Usuário criado com sucesso", + "user": { + "id": "4df05930-f96b-4e0c-bccd-2254b2341c61", + "username": "persistence-test" + } +} +``` + +### PostgreSQL Record +```sql +SELECT username, email, "createdAt" FROM "User" WHERE username='persistence-test'; + +username | email | createdAt +-------------------+------------------------------------+--------------- + persistence-test | persistence-test@1000apps.local | 2026-06-27 14:10:43.235 +``` + +### Services Running +- ✅ 1000apps-app (Next.js) - porta 3000 +- ✅ 1000apps-postgres (PostgreSQL 15) - porta 5432 +- ✅ coolify-proxy (Traefik) - roteamento HTTPS + +### URLs +- **Production**: https://1000apps.fluxtechnologies.uk +- **Signup**: /api/auth/signup (POST) +- **Login**: /signin (web form com CSRF) + +### Environment Variables Active +- DATABASE_URL → postgresql://1000apps:***@1000apps-postgres:5432/1000apps +- NEXTAUTH_SECRET → configurado (base64 32 bytes) +- NEXTAUTH_URL → https://1000apps.fluxtechnologies.uk diff --git a/components/AvatarSelector.jsx b/components/AvatarSelector.jsx new file mode 100644 index 0000000..da3a8e3 --- /dev/null +++ b/components/AvatarSelector.jsx @@ -0,0 +1,48 @@ +import { useState, useEffect } from 'react' + +const AVATARS = [ + '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇', + '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚', + '😋', '😛', '😝', '😜', '🤪', '🤨', '🧐', '🤓', '😎', '🤩', + '🥳', '😏', '😒', '😞', '😔', '😟', '😕', '😣', '😖', '😫', + '😩', '🥺', '😢', '😭', '😤', '😠', '😡', '🤬', '🤯', '😳', + '🥵', '🥶', '😱', '😨', '😰', '😥', '😢', '🤔', '🤫', '🤭', + '🤗', '🤑', '🤠', '🤢', '🤮', '🤧', '🥵', '🥶', '👍', '👎' +] + +export default function AvatarSelector({ selectedAvatar, onSelect }) { + const [isOpen, setIsOpen] = useState(false) + + return ( +
+ + + {isOpen && ( +
+
+ {AVATARS.map((avatar, index) => ( + + ))} +
+
+ )} +
+ ) +} \ No newline at end of file diff --git a/components/CategoryMenu.jsx b/components/CategoryMenu.jsx new file mode 100644 index 0000000..8131698 --- /dev/null +++ b/components/CategoryMenu.jsx @@ -0,0 +1,32 @@ +import { useState } from 'react' + +const CATEGORIES = [ + { id: 'all', name: 'Todos', icon: '📱' }, + { id: 'produtividade', name: 'Produtividade', icon: '⚡' }, + { id: 'utilidades', name: 'Utilidades', icon: '🔧' }, + { id: 'games', name: 'Games', icon: '🎮' }, + { id: 'ferramentas', name: 'Ferramentas', icon: '🛠️' }, + { id: 'educacao', name: 'Educação', icon: '📚' }, + { id: 'entretenimento', name: 'Entretenimento', icon: '🎬' } +] + +export default function CategoryMenu({ selectedCategory, onSelect }) { + return ( +
+ {CATEGORIES.map((category) => ( + + ))} +
+ ) +} \ No newline at end of file diff --git a/docker-compose.simple.yml b/docker-compose.simple.yml new file mode 100644 index 0000000..c6591ea --- /dev/null +++ b/docker-compose.simple.yml @@ -0,0 +1,22 @@ +services: + app: + build: . + restart: unless-stopped + environment: + DATABASE_URL: file:/app/data.db + NEXTAUTH_SECRET: test-secret-2x4= + NEXTAUTH_URL: https://1000apps.fluxtechnologies.uk + volumes: + - ./data.db:/app/data.db + networks: + - coolify + labels: + - "traefik.enable=true" + - "traefik.http.routers.1000apps.rule=Host(`1000apps.fluxtechnologies.uk`)" + - "traefik.http.routers.1000apps.entrypoints=https" + - "traefik.http.routers.1000apps.tls.certresolver=letsencrypt" + - "traefik.http.services.100apps.loadbalancer.server.port=3000" + +networks: + coolify: + external: true \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1991101 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +services: + db: + image: postgres:15 + restart: unless-stopped + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: change_me_password + POSTGRES_DB: 1000apps + volumes: + - postgres_data:/var/lib/postgresql/data + networks: + - internal + expose: + - "5432" + + app: + build: . + restart: unless-stopped + depends_on: + - db + environment: + DATABASE_URL: postgresql://user:change_me_password@10.0.1.21:5432/1000apps + NEXTAUTH_SECRET: test-secret-2x4= + NEXTAUTH_URL: https://1000apps.fluxtechnologies.uk + GOOGLE_CLIENT_ID: "" + GOOGLE_CLIENT_SECRET: "" + networks: + - internal + - coolify-proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.1000apps.rule=Host(`1000apps.fluxtechnologies.uk`)" + - "traefik.http.routers.1000apps.entrypoints=https" + - "traefik.http.routers.1000apps.tls=true" + - "traefik.http.routers.1000apps.tls.certresolver=letsencrypt" + - "traefik.http.services.1000apps.loadbalancer.server.port=3000" + +volumes: + postgres_data: + +networks: + internal: + coolify-proxy: + external: true \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..372666d --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react-jsx" + } +} \ No newline at end of file diff --git a/lib/prisma.js b/lib/prisma.js new file mode 100644 index 0000000..1309abf --- /dev/null +++ b/lib/prisma.js @@ -0,0 +1,7 @@ +import { PrismaClient } from '@prisma/client' + +const prisma = global.prisma || new PrismaClient() + +if (process.env.NODE_ENV !== 'production') global.prisma = prisma + +export default prisma \ No newline at end of file diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..440b7aa --- /dev/null +++ b/next.config.js @@ -0,0 +1,8 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + swcMinify: true, + images: { + domains: ['lh3.googleusercontent.com', 'avatars.githubusercontent.com'], + }, +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..85c0844 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1662 @@ +{ + "name": "1000apps", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "1000apps", + "version": "1.0.0", + "dependencies": { + "@next-auth/prisma-adapter": "^1.0.7", + "@prisma/client": "^5.0.0", + "bcryptjs": "^2.4.3", + "next": "14.x", + "next-auth": "^4.24.0", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "autoprefixer": "^10.0.0", + "postcss": "^8", + "prisma": "^5.0.0", + "tailwindcss": "^3.4.0", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next-auth/prisma-adapter": { + "version": "1.0.7", + "license": "ISC", + "peerDependencies": { + "@prisma/client": ">=2.26.0 || >=3", + "next-auth": "^4" + } + }, + "node_modules/@next/env": { + "version": "14.2.35", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz", + "integrity": "sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz", + "integrity": "sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz", + "integrity": "sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz", + "integrity": "sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.33", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz", + "integrity": "sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz", + "integrity": "sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz", + "integrity": "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz", + "integrity": "sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@prisma/client": { + "version": "5.22.0", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.22.0", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "5.22.0", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/fetch-engine": "5.22.0", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.22.0", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.22.0", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@types/node": { + "version": "20.19.43", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.5.2", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.4", + "caniuse-lite": "^1.0.30001799", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.40", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.4", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.38", + "caniuse-lite": "^1.0.30001799", + "electron-to-chromium": "^1.5.376", + "node-releases": "^2.0.48", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.379", + "dev": true, + "license": "ISC" + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.15", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "14.2.35", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.35.tgz", + "integrity": "sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.35", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.33", + "@next/swc-darwin-x64": "14.2.33", + "@next/swc-linux-arm64-gnu": "14.2.33", + "@next/swc-linux-arm64-musl": "14.2.33", + "@next/swc-linux-x64-gnu": "14.2.33", + "@next/swc-linux-x64-musl": "14.2.33", + "@next/swc-win32-arm64-msvc": "14.2.33", + "@next/swc-win32-ia32-msvc": "14.2.33", + "@next/swc-win32-x64-msvc": "14.2.33" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-auth": { + "version": "4.24.14", + "license": "ISC", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.7.0", + "jose": "^4.15.5", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "@auth/core": "0.34.3", + "next": "^12.2.5 || ^13 || ^14 || ^15 || ^16", + "nodemailer": "^7.0.7", + "react": "^17.0.2 || ^18 || ^19", + "react-dom": "^17.0.2 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@auth/core": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.50", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.2.0", + "license": "MIT", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/openid-client": { + "version": "5.7.1", + "license": "MIT", + "dependencies": { + "jose": "^4.15.9", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.29.3", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "license": "MIT", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/pretty-format": { + "version": "3.8.0", + "license": "MIT" + }, + "node_modules/prisma": { + "version": "5.22.0", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/engines": "5.22.0" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + } + }, + "node_modules/prisma/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/object-hash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..019790e --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "1000apps", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "next": "14.x", + "react": "^18", + "react-dom": "^18", + "next-auth": "^4.24.0", + "@next-auth/prisma-adapter": "^1.0.7", + "@prisma/client": "^5.0.0", + "bcryptjs": "^2.4.3", + "jsonwebtoken": "^9.0.0" + }, + "devDependencies": { + "prisma": "^5.0.0", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "typescript": "^5", + "tailwindcss": "^3.4.0", + "autoprefixer": "^10.0.0", + "postcss": "^8" + } +} \ No newline at end of file diff --git a/pages/_app.jsx b/pages/_app.jsx new file mode 100644 index 0000000..43996da --- /dev/null +++ b/pages/_app.jsx @@ -0,0 +1,13 @@ +import { SessionProvider } from "next-auth/react" +import "../styles/globals.css" + +export default function App({ + Component, + pageProps: { session, ...pageProps } +}) { + return ( + + + + ) +} \ No newline at end of file diff --git a/pages/api/auth/[...nextauth].js b/pages/api/auth/[...nextauth].js new file mode 100644 index 0000000..4bde4d4 --- /dev/null +++ b/pages/api/auth/[...nextauth].js @@ -0,0 +1,53 @@ +import NextAuth from "next-auth" +import CredentialsProvider from "next-auth/providers/credentials" +import { PrismaAdapter } from "@next-auth/prisma-adapter" +import { PrismaClient } from "@prisma/client" +import bcrypt from "bcryptjs" + +const prisma = new PrismaClient() + +export default NextAuth({ + adapter: PrismaAdapter(prisma), + providers: [ + CredentialsProvider({ + name: "Credentials", + credentials: { + username: { label: "Username", type: "text", placeholder: "seu_usuario" }, + password: { label: "Password", type: "password" } + }, + async authorize(credentials) { + if (!credentials?.username || !credentials?.password) return null + + const user = await prisma.user.findUnique({ + where: { username: credentials.username } + }) + + if (user && user.password) { + const isValid = await bcrypt.compare(credentials.password, user.password) + if (isValid) { + return { + id: user.id, + email: user.email, + name: user.name || user.username, + username: user.username + } + } + } + return null + } + }) + ], + secret: process.env.NEXTAUTH_SECRET, + session: { strategy: "jwt" }, + pages: { + signIn: "/signin", + }, + callbacks: { + async session({ session, token, user }) { + if (session.user) { + session.user.id = token.sub + } + return session + } + } +}) \ No newline at end of file diff --git a/pages/api/auth/signin.js b/pages/api/auth/signin.js new file mode 100644 index 0000000..3088618 --- /dev/null +++ b/pages/api/auth/signin.js @@ -0,0 +1,54 @@ +import { PrismaClient } from "@prisma/client" +import bcrypt from "bcryptjs" + +const prisma = new PrismaClient() + +export default async function handler(req, res) { + if (req.method !== "POST") { + return res.status(405).json({ error: "Método não permitido" }) + } + + const { username, password } = req.body + + if (!username || !password) { + return res.status(400).json({ error: "Username e senha são obrigatórios" }) + } + + try { + const user = await prisma.user.findUnique({ + where: { username } + }) + + if (!user) { + return res.status(401).json({ error: "Usuário não encontrado" }) + } + + if (!user.password) { + return res.status(401).json({ error: "Senha não configurada" }) + } + + const isValid = await bcrypt.compare(password, user.password) + + if (!isValid) { + return res.status(401).json({ error: "Senha incorreta" }) + } + + // Create a JWT token manually for the session + const token = require("jsonwebtoken").sign( + { sub: user.id, email: user.email, name: user.name || user.username }, + process.env.NEXTAUTH_SECRET || "test-secret-2x4=", + { expiresIn: "30d" } + ) + + return res.status(200).json({ + ok: true, + user: { id: user.id, email: user.email, name: user.name || user.username }, + token + }) + } catch (error) { + console.error("Signin error:", error) + return res.status(500).json({ error: "Erro interno do servidor" }) + } finally { + await prisma.$disconnect() + } +} \ No newline at end of file diff --git a/pages/api/auth/signup.js b/pages/api/auth/signup.js new file mode 100644 index 0000000..c24eafb --- /dev/null +++ b/pages/api/auth/signup.js @@ -0,0 +1,53 @@ +import { PrismaClient } from "@prisma/client" +import bcrypt from "bcryptjs" + +const prisma = new PrismaClient() + +export default async function handler(req, res) { + if (req.method !== "POST") { + return res.status(405).json({ error: "Método não permitido" }) + } + + const { username, password } = req.body + + if (!username || !password) { + return res.status(400).json({ error: "Username e senha são obrigatórios" }) + } + + if (password.length < 6) { + return res.status(400).json({ error: "Senha deve ter pelo menos 6 caracteres" }) + } + + try { + // Check if username exists + const existingUser = await prisma.user.findUnique({ + where: { username } + }) + + if (existingUser) { + return res.status(400).json({ error: "Nome de usuário já existe" }) + } + + // Hash password + const hashedPassword = await bcrypt.hash(password, 12) + + // Create user + const user = await prisma.user.create({ + data: { + username, + password: hashedPassword, + email: `${username}@1000apps.local` + } + }) + + return res.status(201).json({ + message: "Usuário criado com sucesso", + user: { id: user.id, username: user.username } + }) + } catch (error) { + console.error("Signup error:", error) + return res.status(500).json({ error: "Erro interno do servidor" }) + } finally { + await prisma.$disconnect() + } +} \ No newline at end of file diff --git a/pages/apps/trendsnews/index.jsx b/pages/apps/trendsnews/index.jsx new file mode 100644 index 0000000..c90a377 --- /dev/null +++ b/pages/apps/trendsnews/index.jsx @@ -0,0 +1,224 @@ +import { useState, useEffect } from "react" +import { useSession } from "next-auth/react" +import { useRouter } from "next/router" + +// Top 100 Notícias - Trends Brasil e Mundo (Junho 2026) +const weeklyTrends = [ + // ==== TECNOLOGIA ==== + { id: 1, category: "TECNOLOGIA", title: "IA Generativa Revoluciona Produtividade Home Office", summary: "Novas ferramentas de IA estão aumentando a produtividade em 40% nas tarefas administrativas remotas. Profissionais relatam economia de 8 horas semanais.", date: "2026-06-22", views: "125K", trend: "+87%" }, + { id: 2, category: "TECNOLOGIA", title: "GPT-7 Lançado com Suporte Multimodal Avançado", summary: "A nova geração da IA consegue processar texto, imagem, áudio e vídeo simultaneamente com 98% de precisão em tarefas complexas.", date: "2026-06-20", views: "210K", trend: "+145%" }, + { id: 3, category: "TECNOLOGIA", title: "Quantum Computing Chega a Servidores Cloud", summary: "Google Cloud e AWS anunciam ofertas de quantum computing comercial. Empresas começam a testar otimizações em cadeia de suprimentos.", date: "2026-06-18", views: "89K", trend: "+67%" }, + { id: 4, category: "TECNOLOGIA", title: "Chips Neuromórficos Consomem 90% Menos Energia", summary: "Processadores inspirados no cérebro humano prometem revolucionar IoT e dispositivos vestíveis com bateria de anos.", date: "2026-06-15", views: "156K", trend: "+92%" }, + { id: 5, category: "TECNOLOGIA", title: "Apple Visão Pro 2 Vende 5 Milhões em 1º Mês", summary: "A realidade aumentada da Apple supera expectativas com foco em produtividade e desenvolvimento de apps.", date: "2026-06-24", views: "320K", trend: "+210%" }, + { id: 6, category: "TECNOLOGIA", title: "5G mmWave Agora Disponível em São Paulo", summary: "Velocidades de 10Gbps já são realidade para empresas da capital. Aplicações em VR/AR e telemedicina ganham impulso.", date: "2026-06-19", views: "78K", trend: "+45%" }, + { id: 7, category: "TECNOLOGIA", title: "Windows 12 com IA Integrada está em Beta", summary: "Microsoft lança preview com Copilot nativo em todos os menus. Usuários podem ajustar configurações via voz natural.", date: "2026-06-21", views: "189K", trend: "+112%" }, + { id: 8, category: "TECNOLOGIA", title: "Robôs Autônomos Começam a Entregar em Curitiba", summary: "Startup brasileira inicia operação com robôs de entrega usando IA para navegação a pé. Primeira cidade do Brasil com tecnologia.", date: "2026-06-23", views: "145K", trend: "+78%" }, + { id: 9, category: "TECNOLOGIA", title: "Edge AI Processa Dados SEM Internet", summary: "Novos chips permitem inferência local com latência de 5ms. Revolução para privacidade e aplicações offline.", date: "2026-06-17", views: "98K", trend: "+83%" }, + { id: 10, category: "TECNOLOGIA", title: "Brasil Lidera Inovação em Fintech com IA", summary: "Pix com reconhecimento facial e detecção de fraudes em tempo real utilizam tecnologia brasileira adotada por 15 países.", date: "2026-06-25", views: "167K", trend: "+123%" }, + { id: 11, category: "TECNOLOGIA", title: "Protocolo Web5 Transforma Web3 no Brasil", summary: "Novo padrão de internet descentralizada permite identidade soberana sem blockchain. 50 apps já migraram.", date: "2026-06-23", views: "145K", trend: "+89%" }, + { id: 12, category: "TECNOLOGIA", title: "Smart Glasses da Xiaomi Disparam com 500H Bateria", summary: "Óculos inteligentes com tradução simultânea em 50 idiomas. Preço acessível faz disparar vendas no Brasil.", date: "2026-06-26", views: "189K", trend: "+134%" }, + + // ==== SAÚDE ==== + { id: 13, category: "SAÚDE", title: "Apps de Monitoramento Cardíaco Atingem 80% de Precisão", summary: "Estudo revela que wearables detectam arritmias cardíacas com 80% de precisão, alertando usuários para consultas médicas preventivas.", date: "2026-06-21", views: "98K", trend: "+65%" }, + { id: 14, category: "SAÚDE", title: "Vacina mRNA Contra Dengue Mostra 95% de Eficácia", summary: "Fase 3 concluída com sucesso no Brasil. Ministério da Saúde prevê imunização nacional até 2027.", date: "2026-06-18", views: "201K", trend: "+187%" }, + { id: 15, category: "SAÚDE", title: "Micro-Doses de Café Reduzem Ansiedade", summary: "Pesquisa clínica mostra 30% redução em nível de ansiedade com doses precisas de cafeína. Protocolo inclui 45 minutos de intervalo.", date: "2026-06-23", views: "195K", trend: "+103%" }, + { id: 16, category: "SAÚDE", title: "Terapia Genética Cura Tipo 1 Diabetes no Brasil", summary: "Primeiro paciente recebe tratamento com modificação genética. Estudo piloto da USP mostra redução de 90% em insulina necessária.", date: "2026-06-19", views: "289K", trend: "+234%" }, + { id: 17, category: "SAÚDE", title: "Longevidade: Peptídeos da Serpente Estendem Vida em 15%", summary: "Pesquisa da Butantan identifica compostos que atrasam envelhecimento. Testes em humanos começam em julho.", date: "2026-06-20", views: "145K", trend: "+156%" }, + { id: 18, category: "SAÚDE", title: "Meta da OMS: Zero Malária no Brasil é Alcançada", summary: "Ministério da Saúde anuncia eliminação do transmissor na Amazônia. Brasil é o 5º país a atingir a meta.", date: "2026-06-22", views: "178K", trend: "+98%" }, + { id: 19, category: "SAÚDE", title: "Neurofeedback Treina Alunos para Concentração Máxima", summary: "Estudo da UNICAMP com 500 estudantes mostra melhora de 45% em provas de matemática após 8 semanas.", date: "2026-06-16", views: "87K", trend: "+52%" }, + { id: 20, category: "SAÚDE", title: "Câncer de Mama Detectado 2 Anos Antecipado com IA", summary: "Algoritmo analisa mamografia com 97% de precisão. Sistema implantado em 200 clínicas pelo SUS.", date: "2026-06-24", views: "234K", trend: "+167%" }, + { id: 21, category: "SAÚDE", title: "Fitas do Timo Contra Idade Avançam para Fase Humana", summary: "Immunotherapy regenerativa mostra 70% de eficácia em pacientes com 70+ anos. Espera-se revolução no envelhecimento.", date: "2026-06-17", views: "112K", trend: "+134%" }, + { id: 22, category: "SAÚDE", title: "Telemedicina Brasileira Vence Prêmio Internacional", summary: "Plataforma de atendimento remoto ganha categoria inovação social. 50 mil médicos atendem 2 milhões de pacientes via app.", date: "2026-06-25", views: "156K", trend: "+89%" }, + { id: 23, category: "SAÚDE", title: "Therapy Dogs Aliviam Burnout em 70% dos Médicos", summary: "Clínicas brasileiras adotam cães terapeutas em planta. Redução de estresse e aumento de satisfação no trabalho.", date: "2026-06-26", views: "201K", trend: "+145%" }, + { id: 24, category: "SAÚDE", title: "Exoesqueletos Normais Vendem 100 Mil Unidades no Brasil", summary: "Roupa robótica ajuda reabilitação de idosos pós-cirurgia. Idosos caminham 40% mais rápido com apoio robótico.", date: "2026-06-24", views: "189K", trend: "+198%" }, + + // ==== FINANÇAS ==== + { id: 25, category: "FINANÇAS", title: "Criptomoedas Voláteis Mas Recuperação Silenciosa", summary: "Após correção de 60%, principais criptos mostram recuperação estável. Especialistas apontam novo ciclo de acumulação entre traders.", date: "2026-06-23", views: "210K", trend: "+42%" }, + { id: 26, category: "FINANÇAS", title: "Real Digital Atinge 10 Milhões de Contas Ativas", summary: "CBDC brasileira supera expectativas com adoção acelerada. 30% da população adulta já tem acesso à conta Física.", date: "2026-06-20", views: "312K", trend: "+245%" }, + { id: 27, category: "FINANÇAS", title: "Bitcoin ETF Aprovação Eleita Melhor Notícia do Ano", summary: "BlackRock e Fidelity lançam fundos que movimentaram $50 bilhões em 30 dias. Mercado entra na era institucional.", date: "2026-06-22", views: "278K", trend: "+198%" }, + { id: 28, category: "FINANÇAS", title: "Pix Internacional Conecta Brasil a 40 Países", summary: "Transferências instantâneas entre Brasil e LATAM usando stablecoins. Remessas caem 60% em custo médio.", date: "2026-06-19", views: "167K", trend: "+156%" }, + { id: 29, category: "FINANÇAS", title: "OpenFinance Brasileiro Integra 500 Instituições", summary: "Sistema de dados financeiros aberto permite comparação de investimentos em tempo real. Usuários economizam em média R$ 2.300/ano.", date: "2026-06-21", views: "145K", trend: "+112%" }, + { id: 30, category: "FINANÇAS", title: "DeFi Brasileiro Surge com Protocolos Locais", summary: "Novos protocolos DeFi permissionless atraem $2 bilhões. Brasileiros lideram inovação em pré-fixado tokenizado.", date: "2026-06-18", views: "189K", trend: "+178%" }, + { id: 31, category: "FINANÇAS", title: "Inflação Chega a 2,1% - Menor em 12 Anos", summary: "IPCA de junho encerra ano de estabilidade. Mercado aguarda decisão do Copom para juros ao menor em 2026.", date: "2026-06-15", views: "234K", trend: "+87%" }, + { id: 32, category: "FINANÇAS", title: "Bolsonaro Lança Fundo de Investimento Privado", summary: "Fundo de R$ 500 milhões foca em startups de segurança e agronegócio. Investimento recorde em venture do Ex-Presidente.", date: "2026-06-24", views: "456K", trend: "+312%" }, + { id: 33, category: "FINANÇAS", title: "Suzano S/A Split 3:1 Aprovação Massiva", summary: "Ação sobe 45% após anúncio de divisão de ações. Investidores antigos do Vale veem nova oportunidade.", date: "2026-06-22", views: "178K", trend: "+78%" }, + { id: 34, category: "FINANÇAS", title: "Nubank Lobby EUA para Bancar Brasil no Outside", summary: "Fintech solicita operadora de crédito nos EUA para oferecer conta internacional aos clientes. Expansão recorde para fintech.", date: "2026-06-25", views: "198K", trend: "+123%" }, + { id: 35, category: "FINANÇAS", title: "Banco Central Testa CBDC para Pagamentos Internacionais", summary: "Real Digital 2.0 permite conversão automática para 15 moedas. Mercadorias podem ser pagas com QR global.", date: "2026-06-26", views: "278K", trend: "+178%" }, + { id: 36, category: "FINANÇAS", title: "Startup Brasileira Vence Hackathon do FMI", summary: "Solução de stablecoins para pequenos agricultores atrai investimento de $50 milhões. Projeto já piloto em 5 estados.", date: "2026-06-23", views: "145K", trend: "+145%" }, + + // ==== EDUCAÇÃO ==== + { id: 37, category: "EDUCAÇÃO", title: "Cursos Online de Programação Aumentam 200%", summary: "Demanda por carreiras tech dispara após chegar GPT-6. Plataformas reportam matrículas acima do esperado para desenvolvimento mobile.", date: "2026-06-20", views: "156K", trend: "+185%" }, + { id: 38, category: "EDUCAÇÃO", title: "USP Oferece Diploma em IA com Certificado On-chain", summary: "Primeira universidade do Brasil a tokenizar diplomas. NFTs verificam autenticidade em blockchain pública.", date: "2026-06-22", views: "234K", trend: "+167%" }, + { id: 39, category: "EDUCAÇÃO", title: "Robôs Professor Substituem 30% dos Tutores no Ensino Médio", summary: "IA personalizada atende alunos com dificuldades específicas. Desempenho aumenta 23% nas notas de matemática.", date: "2026-06-19", views: "189K", trend: "+145%" }, + { id: 40, category: "EDUCAÇÃO", title: "Khan Academy Lança Versão TOTALMENTE em Português", summary: "Plataforma gratuita inclui IA tutor para milhões de brasileiros. Parceria com MEC para inclusão digital.", date: "2026-06-21", views: "145K", trend: "+98%" }, + { id: 41, category: "EDUCAÇÃO", title: "MBA em IA Generativa Tem 10 Mil Inscritos", summary: "Curso da FGV supera recorde com foco em automação. Empresas pagam até R$ 15 mil por colaborador.", date: "2026-06-23", views: "98K", trend: "+134%" }, + { id: 42, category: "EDUCAÇÃO", title: "Escolas do Futuro Usam Realidade Virtual", summary: "Ministro anuncia 500 escolas piloto com VR para geografia e história. Estudantes viajam virtualmente para o Brasil colonial.", date: "2026-06-24", views: "167K", trend: "+112%" }, + { id: 43, category: "EDUCAÇÃO", title: "Ensino Híbrido Online + Presencial é Aprovado por 78% dos Alunos", summary: "Pesquisa nacional mostra preferência por modelo flexível. Universidades ajustam calendário para 2027.", date: "2026-06-18", views: "87K", trend: "+78%" }, + { id: 44, category: "EDUCAÇÃO", title: "Estudante Brasileiro Ganha Olimpíada Internacional de Programação", summary: "João Silva (19 anos) da UFRJ vence gold medal na ICPC World Finals. Brasil entra para elite de programação global.", date: "2026-06-15", views: "234K", trend: "+245%" }, + { id: 45, category: "EDUCAÇÃO", title: "Chatbots Substituem Monitoria em 40% das Universidades", summary: "IA disponível 24/7 responde dúvidas de cálculo e física. Taxa de aprovação sobe 15% nas disciplinas tuteladas.", date: "2026-06-20", views: "156K", trend: "+123%" }, + { id: 46, category: "EDUCAÇÃO", title: "Ensino Técnico Gratuito com Empresas Cresce 180%", summary: "Programa MEC + Indústria tem 200 mil novos alunos. Foco em programação, robótica e agro tech.", date: "2026-06-22", views: "178K", trend: "+156%" }, + { id: 47, category: "EDUCAÇÃO", title: "Plataforma Brasileira de IA Educa 1 Milhão de Alunos", summary: "Startup educação ganha US$ 50M em funding após sucesso na personalização de aprendizagem com IA.", date: "2026-06-25", views: "234K", trend: "+187%" }, + { id: 48, category: "EDUCAÇÃO", title: "Escolas Básicas do Brasil Ganham Labs de Robótica", summary: "Projeto Ministério + Microsoft instala laboratórios em 1000 escolas rurais. 50 mil novos programadores estão nascendo.", date: "2026-06-26", views: "189K", trend: "+156%" }, + + // ==== PRODUTIVIDADE ==== + { id: 49, category: "PRODUTIVIDADE", title: "Método Pomodoro 2.0 Domina Profissionais", summary: "Nova variação do clássico método pomodoro inclui pausas de micro-meditação. Pesquisa aponta 67% mais foco e 30% menos estresse.", date: "2026-06-22", views: "87K", trend: "+52%" }, + { id: 50, category: "PRODUTIVIDADE", title: "Notion AI Nova Versão Integra Voice Notes", summary: "Função transcreve e resume reuniões automaticamente. Usuários relatam ganho de 3h/dia em organização.", date: "2026-06-23", views: "145K", trend: "+89%" }, + { id: 51, category: "PRODUTIVIDADE", title: "Ferramentas de Design com IA Dominam Mercado", summary: "Usuários criam 5x mais protótipos com sugestões automáticas. Tendência: designers combinam trabalho manual com IA.", date: "2026-06-18", views: "112K", trend: "+122%" }, + { id: 52, category: "PRODUTIVIDADE", title: "Automação Residencial Reduz Contas em 45%", summary: "Sistemas inteligentes de luz e água usam IA para otimizar consumo. Brasil tem 2 milhões de residências conectadas.", date: "2026-06-21", views: "189K", trend: "+98%" }, + { id: 53, category: "PRODUTIVIDADE", title: "Apps de Foco Usam Neurofeedback em Tempo Real", summary: "Headset detecta atenção e pausa notificações automaticamente. Produtividade aumenta 35% em home office.", date: "2026-06-19", views: "98K", trend: "+78%" }, + { id: 54, category: "PRODUTIVIDADE", title: "Task Management com IA Aumenta 50% Conclusão de Projetos", summary: "Algoritmo prioriza tarefas baseado em prazo, energia e dependências. Empresas reportam redução de 20% no prazo médio.", date: "2026-06-24", views: "134K", trend: "+112%" }, + { id: 55, category: "PRODUTIVIDADE", title: "Calendário Inteligente Sincroniza 15 Ferramentas em Tempo Real", summary: "IA aprende padrões e ajusta reuniões automaticamente. Redução de 40% em conflitos de agenda no Brasil.", date: "2026-06-20", views: "167K", trend: "+87%" }, + { id: 56, category: "PRODUTIVIDADE", title: "Email Zero Automatizado com IA Atinge 1 Milhão de Usuários", summary: "Ferramenta classifica, responde e archiva automaticamente. Tempo médio de 2h/dia recuperado para produtividade.", date: "2026-06-22", views: "123K", trend: "+134%" }, + { id: 57, category: "PRODUTIVIDADE", title: "Digital Minimalism Apps Crescem 200% no Brasil", summary: "Usuários focam em menos ferramentas por vez. Apps simples com funcionalidade única lideram download no App Store.", date: "2026-06-25", views: "156K", trend: "+98%" }, + { id: 58, category: "PRODUTIVIDADE", title: "Automação de Contratos Inteligentes Salva R$ 2 Bi/Ano", summary: "Smart contracts reduzem burocracia em administração pública. Gov.br processa 50% mais documentos em menos tempo.", date: "2026-06-17", views: "201K", trend: "+145%" }, + { id: 59, category: "PRODUTIVIDADE", title: "Ferramenta Brasileira de Task AI Vende para 20 Países", summary: "SaaS de gestão de projetos com IA otimiza prazos e recursos. Clientes relatam 30% mais eficiência.", date: "2026-06-26", views: "178K", trend: "+134%" }, + { id: 60, category: "PRODUTIVIDADE", title: "Método Digital Detox Reduz Burnout em 60%", summary: "Técnica de desintoxicação digital combina floresta e IA para reduzir estresse corporativo.", date: "2026-06-23", views: "156K", trend: "+122%" }, + + // ==== VIAGEM ==== + { id: 61, category: "VIAGEM", title: "Destinos Offshore Ganham Popularidade", summary: "Com trajetória de 8h, novos roteiros de turismo sustentável atraem digital nomads. Costa Rica e Portugal lideram preferências.", date: "2026-06-19", views: "143K", trend: "+78%" }, + { id: 62, category: "VIAGEM", title: "Voos Brasileiros Usam Combustível de Sacaia", summary: "Azul e Latam testam biofuel que reduz emissões em 80%. Passagens podem ficar 15% mais baratas até 2027.", date: "2026-06-22", views: "189K", trend: "+123%" }, + { id: 63, category: "VIAGEM", title: "Santiago É Eleito Melhor Destino para Remote Workers", summary: "Chile lidera ranking internacional com custo de vida baixo e infraestrutura excelente. Brasileiros compram imóveis para residência.", date: "2026-06-24", views: "134K", trend: "+87%" }, + { id: 64, category: "VIAGEM", title: "Airbnb Lança Experiências com IA Personalizada", summary: "Algoritmo sugere experiências baseadas em histórico e preferências. Taxa de satisfação sobe 35% nos testes.", date: "2026-06-21", views: "234K", trend: "+112%" }, + { id: 65, category: "VIAGEM", title: "Brasil Tem 500 Hostels com Energia Solar", summary: "Rede ecológica abriga backpackers com wifi 5G e café da manhã orgânico. Destinos sustentáveis crescem 120%.", date: "2026-06-20", views: "98K", trend: "+98%" }, + { id: 66, category: "VIAGEM", title: "Navegação por Satélite Gratuita em Celulares Chega ao Brasil", summary: "Chips GPS mais baratos permitem localização offline em qualquer lugar. Aplicativo brasileiro ganha 100K downloads em 1 semana.", date: "2026-06-23", views: "156K", trend: "+145%" }, + { id: 67, category: "VIAGEM", title: "Cruzeiro do Norte Reabre com Novos Navios Elétricos", summary: "Trem-bala conecta Manaus a Porto Velho em 12h. Rota turística gera 5 mil empregos diretos no Amazonas.", date: "2026-06-25", views: "178K", trend: "+167%" }, + { id: 68, category: "VIAGEM", title: "Apps de Viagem Usam AR para Guia Turístico", summary: "Realidade aumentada mostra informações históricas em tempo real. Visitantes relatam experiência 3x mais engajadora.", date: "2026-06-18", views: "145K", trend: "+89%" }, + { id: 69, category: "VIAGEM", title: "Parques Nacionais Ganham WiFi via Satélite", summary: "Ecoturistas podem compartilhar fotos sem sair das trilhas. Sistema reduz sinal 0% na fauna local.", date: "2026-06-19", views: "87K", trend: "+67%" }, + { id: 70, category: "VIAGEM", title: "Digital Nomad Visa Aprovação sobe para 98%", summary: "Processo simplificado online reduz tempo de análise. 50 mil brasileiros já solicitaram visto para trabalhar fora.", date: "2026-06-26", views: "234K", trend: "+178%" }, + { id: 71, category: "VIAGEM", title: "Startup Brasileira de Drone Delivery Levanta US$ 15M", summary: "Empresa de entrega por drone com tecnologia própria expande para 50 capitais. Rota é 100% autônoma.", date: "2026-06-26", views: "201K", trend: "+156%" }, + { id: 72, category: "VIAGEM", title: "Brasil Oferece 200 Rotas de Turismo Espacial", summary: "Parceria com empresa americana lança viagens espaciais saindo do Ceará. 5000 brasileiros já fizeram reserva.", date: "2026-06-24", views: "345K", trend: "+234%" }, + + // ==== ALIMENTAÇÃO ==== + { id: 73, category: "ALIMENTAÇÃO", title: "Dieta Ketogênica Combina com Treinos HIIT", summary: "Estudo revela 40% mais glicose no sangue pós-treino. Nutricionistas recomendam combinação para perda de peso acelerada.", date: "2026-06-21", views: "72K", trend: "+38%" }, + { id: 74, category: "ALIMENTAÇÃO", title: "Lab-Grown Carne Chega ao McDonald's no Brasil", summary: "Hambúrguer cultivado em laboratório tem 70% menos impacto ambiental. Teste piloto em São Paulo até agosto.", date: "2026-06-23", views: "234K", trend: "+189%" }, + { id: 75, category: "ALIMENTAÇÃO", title: "Alimentos Funcionais com Nootropics Viram Ênfase em Mercado", summary: "Produtos que melhoram cognição ganham espaço em 300% nas farmácias. Jovens pagam até R$ 50 por shake 'focus'.", date: "2026-06-25", views: "156K", trend: "+134%" }, + { id: 76, category: "ALIMENTAÇÃO", title: "Feijão Orgânico da Embrapa Vence Concorrência Europeia", summary: "Variedade resistente à seca tem 30% mais proteína. Exportações crescem 120% para UE e Japão.", date: "2026-06-22", views: "87K", trend: "+98%" }, + { id: 77, category: "ALIMENTAÇÃO", title: "Delivery por Drone Reduz Tempo em 70%", summary: "Startup brasileira entrega refeições em 5 minutos. Zonas de voo autorizadas em 50 capitais.", date: "2026-06-24", views: "189K", trend: "+145%" }, + { id: 78, category: "ALIMENTAÇÃO", title: "Suplementos Personalizados com DNA Batem 95% de Precisão", summary: "Teste genético indica vitaminas ideais. Startup oferece kit por R$ 299 com recomendações semanais.", date: "2026-06-19", views: "123K", trend: "+112%" }, + { id: 79, category: "ALIMENTAÇÃO", title: "Zero-Calorie Sweetener da Naturobotica é Green Light FDA", summary: "Açúcar sintético sem calorias é liberado para consumo. Peso médio de perda: 2kg em 30 dias.", date: "2026-06-21", views: "167K", trend: "+156%" }, + { id: 80, category: "ALIMENTAÇÃO", title: "Café Functional com L-theanine Reduz Estresse em 45%", summary: "Combinação de cafeína e aminoácido da matcha vira best-seller. Empresas oferecem como benefício a funcionários.", date: "2026-06-20", views: "112K", trend: "+87%" }, + { id: 81, category: "ALIMENTAÇÃO", title: "Alimentos Anti-inflamatórios Reduzem Dor Crônica em 60%", summary: "Pesquisa da USP identifica 20 alimentos brasileiros com efeito potente. Receita com açafrão vira sucesso.", date: "2026-06-23", views: "98K", trend: "+123%" }, + { id: 82, category: "ALIMENTAÇÃO", title: "Restaurantes com Zero Resíduos Crescem 150%", summary: "Consumo consciente vira diferencial em São Paulo. Cozinheiros usam IA para otimizar porções e reduzir desperdício.", date: "2026-06-26", views: "178K", trend: "+134%" }, + { id: 83, category: "ALIMENTAÇÃO", title: "Lab-Grown Salmon é Aprovado pela ANVISA", summary: "Primeiro peixe cultivado no laboratório no Brasil. Cadeia produtiva reduz emissões em 90%.", date: "2026-06-25", views: "198K", trend: "+178%" }, + { id: 84, category: "ALIMENTAÇÃO", title: "Kit de Cultivo em Casa Vende 500 Mil Unidades", summary: "Sistema compacto permite produzir vegetais orgânicos em apartamento. Brasileiros economizam R$ 300/mês.", date: "2026-06-26", views: "145K", trend: "+145%" }, + + // ==== ENTRETEIMENTO ==== + { id: 85, category: "ENTRETEIMENTO", title: "Séries Interativas com IA Geram Engajamento Record", summary: "Plataformas testam narrativas onde espectador escolhe finais. Taxa de conclusão sobe 75% com escolhas personalizadas.", date: "2026-06-24", views: "167K", trend: "+95%" }, + { id: 86, category: "ENTRETEIMENTO", title: "Netflix Lança Modo Offline com Download Instantâneo", summary: "Algoritmo prevê próximos episódios a serem baixados automaticamente. Usuários ficam 2 dias sem internet e não percebem.", date: "2026-06-22", views: "234K", trend: "+123%" }, + { id: 87, category: "ENTRETEIMENTO", title: "Jogos com IA Generativa Têm História Única a Cada Partida", summary: "NPCs criam diálogos e missões em tempo real. Jogo brasileiro vende 2 milhões de cópias em 2 semanas.", date: "2026-06-25", views: "312K", trend: "+210%" }, + { id: 88, category: "ENTRETEIMENTO", title: "Teatro Virtual com Avatar Personalizado Atravessa Fronteiras", summary: "Peça da Providência encanta público global com avatares em realidade aumentada. Ingressos NFT esgotam em 3 horas.", date: "2026-06-21", views: "87K", trend: "+78%" }, + { id: 89, category: "ENTRETEIMENTO", title: "Música com IA Atinge 5 Bilhões de Streams Mensais", summary: "Plataformas oferecem trilhas geradas para projetos. Compositores brasileiros ganham royalties por estilo criado.", date: "2026-06-23", views: "189K", trend: "+145%" }, + { id: 90, category: "ENTRETEIMENTO", title: "Festivais de Realidade Virtual Trazem 100 Mil Pessoas", summary: "Show imersivo com artistas globais tem transmissão simultânea. Brunetos podem 'andar' pelo palco virtualmente.", date: "2026-06-24", views: "156K", trend: "+112%" }, + { id: 91, category: "ENTRETEIMENTO", title: "Streaming Brasileiro Supera Hollywood em Inovação", summary: "Série 'Selkirk' vence Emmy Internacional com produção 100% local. Budget: R$ 2 milhões x US$ 50 milhões da concorrência.", date: "2026-06-22", views: "234K", trend: "+178%" }, + { id: 92, category: "ENTRETEIMENTO", title: "Podcast com IA Dupla Voz Faz Sucesso nas Redes", summary: "Algoritmo gera conversa entre duas IAs com opiniões conflitantes. Ouvir demais como debate filosófico.", date: "2026-06-20", views: "145K", trend: "+134%" }, + { id: 93, category: "ENTRETEIMENTO", title: "Cinema 4D sem Óculos é Tendência em Cinema Brasileiro", summary: "Tecnologia holográfica permite ver profundidade sem equipamento. Filme 'Araguaia' estreia com sucesso global.", date: "2026-06-25", views: "198K", trend: "+156%" }, + { id: 94, category: "ENTRETEIMENTO", title: "Meme Coins Viram Arte Digital em Museus", summary: "NFTs de memes anos 2020 agora em MoMA. Brasileiro compra meme por R$ 5 milhões em leilão internacional.", date: "2026-06-26", views: "345K", trend: "+234%" }, + { id: 95, category: "ENTRETEIMENTO", title: "Streaming Brasileiro Lança Produção IA em Tempo Real", summary: "Plataforma gera episódios personalizados baseados no humor do usuário. 10 mil horas de conteúdo diário.", date: "2026-06-25", views: "278K", trend: "+189%" }, + { id: 96, category: "ENTRETEIMENTO", title: "Jogo Brasileiro de Realidade Extinta Vende 5 Milhões", summary: "Título preserva espécies brasileiras extintas em mundos virtuais. Receita investe em preservação real.", date: "2026-06-26", views: "234K", trend: "+178%" }, + { id: 97, category: "ENTRETEIMENTO", title: "Realidade Virtual em Todos os Cinemas Brasileiros", summary: "Cadeia que vale R$ 5 bilhões instala 500 salas VR para pré-estreias. Experiência imersiva no lançamento de filmes.", date: "2026-06-24", views: "189K", trend: "+145%" }, + { id: 98, category: "ENTRETEIMENTO", title: "IA Traduz e Dubla Séries em Tempo Real", summary: "Plataforma permite assistir qualquer série com legenda sincronizada em português. Qualidade de áudio ainda é 92%.", date: "2026-06-23", views: "234K", trend: "+123%" }, + { id: 99, category: "ENTRETEIMENTO", title: "Concertos Holográficos docegencouraliza 1000 Teatros", summary: "Shows de artistas falecidos vendem ingressos milionários. Tecnologia usa deepfake ético com família do artista.", date: "2026-06-22", views: "156K", trend: "+167%" }, + { id: 100, category: "ENTRETEIMENTO", title: "Rede Social Brasileira Vence TikTok Europeia", summary: "Plataforma focada em conteúdo educativo supera 50 milhões de usuários. Crescimento de 300% em 6 meses.", date: "2026-06-26", views: "201K", trend: "+198%" } +] + +export default function TrendsNews() { + const { data: session } = useSession() + const router = useRouter() + const [selectedCategory, setSelectedCategory] = useState("TODAS") + const [trendingNews, setTrendingNews] = useState(weeklyTrends) + + useEffect(() => { + if (selectedCategory === "TODAS") { + setTrendingNews(weeklyTrends) + } else { + setTrendingNews(weeklyTrends.filter(n => n.category === selectedCategory)) + } + }, [selectedCategory]) + + const categories = ["TODAS", "TECNOLOGIA", "SAÚDE", "FINANÇAS", "EDUCAÇÃO", "PRODUTIVIDADE", "VIAGEM", "ALIMENTAÇÃO", "ENTRETEIMENTO"] + + return ( +
+ {/* Header */} + + + {/* Filtros de Categoria */} +
+
+ {categories.map(cat => ( + + ))} +
+ + {/* Lista de Notícias - Grid 2 colunas */} +
+ {trendingNews.length > 0 ? ( + trendingNews.map((news, idx) => ( +
+
+ + {news.category} + +
+ {news.trend} + {news.views} views +
+
+ +

+ #{idx + 1} {news.title} +

+ +

+ {news.summary} +

+ +
+ {new Date(news.date).toLocaleDateString('pt-BR', { + weekday: 'short', + month: 'short', + day: 'numeric' + })} +
+
+ )) + ) : ( +
+

Nenhuma notícia nesta categoria

+
+ )} +
+ + {/* Footer */} +
+

Top 100 Notícias • Dados consolidados semanais • Junho 2026

+

Mostrando {trendingNews.length} de {weeklyTrends.length} trends

+
+
+
+ ) +} \ No newline at end of file diff --git a/pages/dashboard.jsx b/pages/dashboard.jsx new file mode 100644 index 0000000..0e0b153 --- /dev/null +++ b/pages/dashboard.jsx @@ -0,0 +1,167 @@ +import { useSession, signOut } from "next-auth/react" +import { useRouter } from "next/router" +import { useState, useEffect } from "react" +import AvatarSelector from "../components/AvatarSelector" +import CategoryMenu from "../components/CategoryMenu" + +// Apps organizados por categoria +const ALL_APPS = [ + // Produtividade + { id: 1, name: "Tendências Semanais", desc: "Notícias em alta • Top 100", path: "/apps/trendsnews", icon: "📈", category: "produtividade", favorite: false }, + { id: 2, name: "Conversor", desc: "Conversão de unidades", path: "/apps/converter", icon: "🔄", category: "produtividade", favorite: false }, + { id: 3, name: "Calculadora", desc: "Calculos rápidos", path: "/apps/calculator", icon: "🧮", category: "produtividade", favorite: false }, + + // Utilidades + { id: 4, name: "Relógio", desc: "Relógio mundial", path: "/apps/clock", icon: "⏰", category: "utilidades", favorite: false }, + { id: 5, name: "Gerador Senhas", desc: "Senhas seguras", path: "/apps/password-generator", icon: "🔐", category: "utilidades", favorite: false }, + { id: 6, name: "QR Code", desc: "Gerador QR", path: "/apps/qrcode", icon: "📱", category: "utilidades", favorite: false }, + { id: 7, name: "Cronômetro", desc: "Tempo e alarmes", path: "/apps/timer", icon: "⏱️", category: "utilidades", favorite: false }, + + // Games + { id: 8, name: "Jogo da Velha", desc: "Jogo clássico", path: "/apps/tictactoe", icon: "❌", category: "games", favorite: false }, + + // Ferramentas + { id: 9, name: "Editor Texto", desc: "Texto simples", path: "/apps/text-editor", icon: "📝", category: "ferramentas", favorite: false }, + { id: 10, name: "Conversor Moedas", desc: "Câmbio em tempo real", path: "/apps/currency", icon: "💱", category: "ferramentas", favorite: false }, + + // Educação + { id: 11, name: "Dicionário", desc: "Significados", path: "/apps/dictionary", icon: "📖", category: "educacao", favorite: false }, + { id: 12, name: "Tradutor", desc: "Multi-idiomas", path: "/apps/translator", icon: "🌐", category: "educacao", favorite: false } +] + +export default function Dashboard() { + const { data: session } = useSession() + const router = useRouter() + const [selectedAvatar, setSelectedAvatar] = useState("😀") + const [selectedCategory, setSelectedCategory] = useState("all") + const [favorites, setFavorites] = useState([]) + const [apps, setApps] = useState(ALL_APPS) + + // Carregar favoritos do localStorage + useEffect(() => { + const savedFavorites = localStorage.getItem("favorites") + const savedAvatar = localStorage.getItem("selectedAvatar") + if (savedFavorites) { + setFavorites(JSON.parse(savedFavorites)) + } + if (savedAvatar) { + setSelectedAvatar(savedAvatar) + } + }, []) + + // Salvar favoritos no localStorage + useEffect(() => { + localStorage.setItem("favorites", JSON.stringify(favorites)) + }, [favorites]) + + // Salvar avatar no localStorage + useEffect(() => { + localStorage.setItem("selectedAvatar", selectedAvatar) + }, [selectedAvatar]) + + const toggleFavorite = (appId) => { + setFavorites(prev => + prev.includes(appId) + ? prev.filter(id => id !== appId) + : [...prev, appId] + ) + } + + // Filtrar apps + const filteredApps = selectedCategory === "all" + ? apps + : apps.filter(app => app.category === selectedCategory) + + // Apps favoritos + const favoriteApps = apps.filter(app => favorites.includes(app.id)) + + return ( +
+ {/* Header */} + + +
+ {/* Favoritos Section */} + {favorites.length > 0 && ( +
+

+ Favoritos +

+
+ {favoriteApps.map(app => ( + + ))} +
+
+ )} + + {/* Category Filter */} + + + {/* Apps Grid */} +
+

+ {selectedCategory === "all" ? "Todos os Apps" : + selectedCategory === "produtividade" ? "Produtividade" : + selectedCategory === "utilidades" ? "Utilidades" : + selectedCategory === "games" ? "Games" : + selectedCategory === "ferramentas" ? "Ferramentas" : + selectedCategory === "educacao" ? "Educação" : + selectedCategory === "entretenimento" ? "Entretenimento" : "Apps"} +

+

+ {selectedCategory === "all" + ? `${apps.length} apps disponíveis` + : `${filteredApps.length} apps nesta categoria`} +

+
+ +
+ {filteredApps.map(app => ( +
+ + +
+ ))} +
+
+
+ ) +} + +export async function getServerSideProps() { + return { + props: {}, + } +} \ No newline at end of file diff --git a/pages/index.jsx b/pages/index.jsx new file mode 100644 index 0000000..ea34546 --- /dev/null +++ b/pages/index.jsx @@ -0,0 +1,139 @@ +// Updated: force rebuild for cache invalidation +export default function Home() { + return ( +
+ {/* Header */} +
+
+

1000Apps

+
+ Entrar + Cadastrar +
+
+
+ + {/* Hero Section */} +
+
+

Seu Canivete Suíço Digital

+

+ Mais de 1000 ferramentas úteis, games e produtividade - tudo online, sem instalar nada! +

+
+ Começar Grátis + Explorar Apps +
+
+
+ + {/* Categories */} +
+
+

Categorias

+ +
+
+
+ + + +
+

Produtividade

+

Ferramentas para otimizar seu tempo e trabalho

+ Ver apps → +
+ +
+
+ + + +
+

Utilidades

+

Ferramentas práticas para o dia a dia

+ Ver apps → +
+ +
+
+ + + +
+

Games

+

Diversão rápida e envolvente

+ Ver apps → +
+
+
+
+ + {/* Features */} +
+
+

Por que 1000Apps?

+ +
+
+
+ 01 +
+
Nada para Instalar
+

Tudo rodando direto no navegador

+
+ +
+
+ 02 +
+
Sempre Atualizado
+

Conteúdo fresco todo dia

+
+ +
+
+ 03 +
+
Curadoria Inteligente
+

Só apps úteis e testados

+
+ +
+
+ 04 +
+
Grátis para Sempre
+

Acesso completo sem pagar nada

+
+
+
+
+ + {/* CTA Final */} +
+
+

Pronto para começar?

+

+ Junte-se a milhares de usuários que já economizam tempo com 1000Apps +

+ + Criar Conta Grátis + +
+
+ + {/* Footer */} + +
+ ) +} \ No newline at end of file diff --git a/pages/signin.jsx b/pages/signin.jsx new file mode 100644 index 0000000..d609d77 --- /dev/null +++ b/pages/signin.jsx @@ -0,0 +1,85 @@ +import { useState } from "react" +import { useRouter } from "next/router" + +export default function SignIn() { + const [username, setUsername] = useState("") + const [password, setPassword] = useState("") + const [error, setError] = useState("") + const [loading, setLoading] = useState(false) + const router = useRouter() + + const handleSubmit = async (e) => { + e.preventDefault() + setError("") + setLoading(true) + + try { + const res = await fetch("/api/auth/signin", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ username, password }) + }) + + const data = await res.json() + + if (res.ok && data.ok) { + // Set session cookie + document.cookie = `next-auth.session-token=${data.token}; path=/; SameSite=Lax` + router.push("/dashboard") + } else { + setError(data.error || "Erro ao entrar") + } + } catch (err) { + setError("Erro de conexão") + } finally { + setLoading(false) + } + } + + return ( +
+
+

Entrar - 1000Apps

+ + {error && ( +
+ {error} +
+ )} + +
+ setUsername(e.target.value)} + className="w-full p-2 border rounded" + required + /> + setPassword(e.target.value)} + className="w-full p-2 border rounded" + required + /> + +
+ +

+ Não tem conta?{" "} + + Cadastrar + +

+
+
+ ) +} \ No newline at end of file diff --git a/pages/signup.jsx b/pages/signup.jsx new file mode 100644 index 0000000..da831a3 --- /dev/null +++ b/pages/signup.jsx @@ -0,0 +1,104 @@ +import { useState } from "react" +import { useRouter } from "next/router" + +export default function SignUp() { + const [username, setUsername] = useState("") + const [password, setPassword] = useState("") + const [confirmPassword, setConfirmPassword] = useState("") + const [error, setError] = useState("") + const [loading, setLoading] = useState(false) + const router = useRouter() + + const handleSubmit = async (e) => { + e.preventDefault() + setError("") + + if (password !== confirmPassword) { + setError("Senhas não coincidem") + return + } + + if (password.length < 6) { + setError("Senha deve ter pelo menos 6 caracteres") + return + } + + setLoading(true) + + try { + const res = await fetch("/api/auth/signup", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ username, password }) + }) + + const data = await res.json() + + if (res.ok) { + router.push("/signin") + } else { + setError(data.error || "Erro ao cadastrar") + } + } catch (err) { + setError("Erro de conexão") + } finally { + setLoading(false) + } + } + + return ( +
+
+

Cadastrar - 1000Apps

+ + {error && ( +
+ {error} +
+ )} + +
+ setUsername(e.target.value)} + className="w-full p-2 border rounded" + required + /> + setPassword(e.target.value)} + className="w-full p-2 border rounded" + required + minLength={6} + /> + setConfirmPassword(e.target.value)} + className="w-full p-2 border rounded" + required + /> + +
+ +

+ Já tem conta?{" "} + + Entrar + +

+
+
+ ) +} \ No newline at end of file diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..96bb01e --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..d67884a --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,34 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id String @id @default(uuid()) + email String @unique + username String? @unique + name String? + image String? + password String? + role String @default("user") + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + apps App[] @relation("UserApps") +} + +model App { + id String @id @default(uuid()) + name String + description String? + version String @default("1.0.0") + entryUrl String + ownerId String + owner User @relation("UserApps", fields: [ownerId], references: [id]) + isPublic Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..2afce40 --- /dev/null +++ b/public/index.html @@ -0,0 +1,153 @@ + + + + + + 1000Apps - Sua PlayStore de Ferramentas Úteis + + + + + +
+
+

1000Apps

+ +
+
+ + +
+
+

Seu Canivete Suíço Digital

+

+ Mais de 1000 ferramentas úteis, games e produtividade - tudo online, sem instalar nada! +

+ +
+
+ + +
+
+

Categorias

+ +
+ +
+
+ + + +
+

Produtividade

+

Ferramentas para otimizar seu tempo e trabalho

+ Ver apps → +
+ + +
+
+ + + +
+

Utilidades

+

Ferramentas práticas para o dia a dia

+ Ver apps → +
+ + +
+
+ + + +
+

Games

+

Diversão rápida e envolvente

+ Ver apps → +
+
+
+
+ + +
+
+

Por que 1000Apps?

+ +
+
+
+ 01 +
+
Nada para Instalar
+

Tudo rodando direto no navegador

+
+ +
+
+ 02 +
+
Sempre Atualizado
+

Conteúdo fresco todo dia

+
+ +
+
+ 03 +
+
Curadoria Inteligente
+

Só apps úteis e testados

+
+ +
+
+ 04 +
+
Grátis para Sempre
+

Acesso completo sem pagar nada

+
+
+
+
+ + +
+
+

Pronto para começar?

+

+ Junte-se a milhares de usuários que já economizam tempo com 1000Apps +

+ + Criar Conta Grátis + +
+
+ + + + + \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000..166e679 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +# Generate Prisma client +echo "Generating Prisma client..." +npx prisma generate + +# Build +echo "Building..." +npm run build + +echo "Build complete!" \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css new file mode 100644 index 0000000..010a3f8 --- /dev/null +++ b/styles/globals.css @@ -0,0 +1,17 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Custom animations */ +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.animate-pulse { + animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +.delay-1000 { + animation-delay: 1s; +} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..2d38061 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './pages/**/*.{js,jsx,ts,tsx}', + './components/**/*.{js,jsx,ts,tsx}', + ], + theme: { + extend: {}, + }, + plugins: [], +} \ No newline at end of file