From 64c950886aefb043e65b5c8713349c37b691fcf4 Mon Sep 17 00:00:00 2001 From: "[dyad]" Date: Sat, 1 Aug 2026 13:19:17 +0200 Subject: [PATCH] =?UTF-8?q?[dyad]=20Giri=C5=9F=20hatalar=C4=B1n=C4=B1=20do?= =?UTF-8?q?=C4=9Frula?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 ++ package.json | 4 +- playwright-dyad.config.ts | 20 +++++++ pnpm-lock.yaml | 55 ++++++++++++++++--- src/components/auth-view.tsx | 103 +---------------------------------- 5 files changed, 77 insertions(+), 111 deletions(-) create mode 100644 playwright-dyad.config.ts diff --git a/.gitignore b/.gitignore index d0be1c9..e6f3be1 100755 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,9 @@ Caddyfile # lock files (optional - some projects include them) bun.lock .dyad/ + +# Playwright test artifacts +/test-results/ +/playwright-report/ +/playwright/.cache/ +.last-run.json diff --git a/package.json b/package.json index e698799..e231282 100755 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "db:generate": "prisma generate", "db:migrate": "prisma migrate dev", "db:reset": "prisma migrate reset", - "db:seed": "bun prisma/seed.ts" + "db:seed": "bun prisma/seed.ts", + "test": "playwright test --config playwright-dyad.config.ts" }, "dependencies": { "@dnd-kit/core": "^6.3.1", @@ -102,6 +103,7 @@ "zustand": "^5.0.6" }, "devDependencies": { + "@playwright/test": "^1.62.1", "@tailwindcss/postcss": "^4", "@types/bcryptjs": "^3.0.0", "@types/react": "^19", diff --git a/playwright-dyad.config.ts b/playwright-dyad.config.ts new file mode 100644 index 0000000..327e7b6 --- /dev/null +++ b/playwright-dyad.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "@playwright/test"; + +// Generated by Dyad. The dev server is started separately by Dyad's +// preview, so we point baseURL at the already-running proxy URL (passed via +// env) rather than using Playwright's `webServer` (which would double-start +// the app). +// // Uses your installed Google Chrome (no extra browser download). +export default defineConfig({ + testDir: "./e2e-tests", + // Run serially against the single dev server. + workers: 1, + fullyParallel: false, + reporter: [["json", { outputFile: "test-results/results.json" }]], + use: { + baseURL: process.env.DYAD_TEST_BASE_URL || "http://localhost:32100", + channel: "chrome", + screenshot: "only-on-failure", + trace: "retain-on-failure", + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3eb838..9768924 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -148,13 +148,13 @@ importers: version: 0.525.0(react@19.2.8) next: specifier: ^16.1.1 - version: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-auth: specifier: ^4.24.11 - version: 4.24.15(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 4.24.15(next@16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-intl: specifier: ^4.3.4 - version: 4.13.4(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(typescript@5.9.3) + version: 4.13.4(next@16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(typescript@5.9.3) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -219,6 +219,9 @@ importers: specifier: ^5.0.6 version: 5.0.14(@types/react@19.2.17)(react@19.2.8)(use-sync-external-store@1.6.0(react@19.2.8)) devDependencies: + '@playwright/test': + specifier: ^1.62.1 + version: 1.62.1 '@tailwindcss/postcss': specifier: ^4 version: 4.3.3 @@ -1118,6 +1121,11 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} + '@playwright/test@1.62.1': + resolution: {integrity: sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==} + engines: {node: '>=20'} + hasBin: true + '@prisma/client@6.19.3': resolution: {integrity: sha512-mKq3jQFhjvko5LTJFHGilsuQs+W+T3Gm451NzuTDGQxwCzwXHYnIu2zGkRoW+Exq3Rob7yp2MfzSrdIiZVhrBg==} engines: {node: '>=18.18'} @@ -3035,6 +3043,11 @@ packages: react-dom: optional: true + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -3932,6 +3945,16 @@ packages: pkg-types@2.3.1: resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} + playwright-core@1.62.1: + resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==} + engines: {node: '>=20'} + hasBin: true + + playwright@1.62.1: + resolution: {integrity: sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==} + engines: {node: '>=20'} + hasBin: true + po-parser@2.1.1: resolution: {integrity: sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==} @@ -5718,6 +5741,10 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 + '@playwright/test@1.62.1': + dependencies: + playwright: 1.62.1 + '@prisma/client@6.19.3(prisma@6.19.3(typescript@5.9.3))(typescript@5.9.3)': optionalDependencies: prisma: 6.19.3(typescript@5.9.3) @@ -7772,6 +7799,9 @@ snapshots: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) + fsevents@2.3.2: + optional: true + function-bind@1.1.2: {} function.prototype.name@1.2.0: @@ -8715,13 +8745,13 @@ snapshots: negotiator@1.0.0: {} - next-auth@4.24.15(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + next-auth@4.24.15(next@16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@babel/runtime': 7.29.7 '@panva/hkdf': 1.2.1 cookie: 0.7.2 jose: 4.15.9 - next: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next: 16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) oauth: 0.9.15 openid-client: 5.7.1 preact: 10.29.7(preact-render-to-string@5.2.6) @@ -8732,14 +8762,14 @@ snapshots: next-intl-swc-plugin-extractor@4.13.4: {} - next-intl@4.13.4(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(typescript@5.9.3): + next-intl@4.13.4(next@16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(typescript@5.9.3): dependencies: '@formatjs/intl-localematcher': 0.8.13 '@parcel/watcher': 2.6.0 '@swc/core': 1.15.47 icu-minify: 4.13.4 negotiator: 1.0.0 - next: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next: 16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-intl-swc-plugin-extractor: 4.13.4 po-parser: 2.1.1 react: 19.2.8 @@ -8756,7 +8786,7 @@ snapshots: next-tick@1.1.0: {} - next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + next@16.2.12(@babel/core@7.29.7)(@playwright/test@1.62.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@next/env': 16.2.12 '@swc/helpers': 0.5.15 @@ -8775,6 +8805,7 @@ snapshots: '@next/swc-linux-x64-musl': 16.2.12 '@next/swc-win32-arm64-msvc': 16.2.12 '@next/swc-win32-x64-msvc': 16.2.12 + '@playwright/test': 1.62.1 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' @@ -8927,6 +8958,14 @@ snapshots: exsolve: 1.1.1 pathe: 2.0.3 + playwright-core@1.62.1: {} + + playwright@1.62.1: + dependencies: + playwright-core: 1.62.1 + optionalDependencies: + fsevents: 2.3.2 + po-parser@2.1.1: {} possible-typed-array-names@1.1.0: {} diff --git a/src/components/auth-view.tsx b/src/components/auth-view.tsx index 600fa36..bbe3a8a 100755 --- a/src/components/auth-view.tsx +++ b/src/components/auth-view.tsx @@ -2,7 +2,7 @@ import React, { useState, useMemo } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; -import { BookOpen, Mail, Lock, User, ArrowRight, GraduationCap, Heart, Sparkles, Flower2, Eye, EyeOff, KeyRound, Info, Shield, Leaf, Users as UsersIcon, HelpCircle, BarChart3, LockKeyhole, GitBranch, CheckCircle2, XCircle, Globe, Github, Chrome } from 'lucide-react'; +import { BookOpen, Mail, Lock, User, ArrowRight, GraduationCap, Heart, Sparkles, Flower2, Eye, EyeOff, KeyRound, Info, Shield, Leaf, Users as UsersIcon, HelpCircle, LockKeyhole, GitBranch, CheckCircle2, XCircle } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; @@ -275,56 +275,6 @@ function LeftIllustration({ loginRole }: { loginRole: LoginRole }) { ); } -/* ─── Features section below form ───────────────────────────── */ -function FeaturesSection() { - const features = [ - { icon: BarChart3, labelKey: 'auth.feature_grading', descKey: 'auth.feature_grading_desc', color: 'emerald' }, - { icon: GraduationCap, labelKey: 'auth.feature_attendance', descKey: 'auth.feature_attendance_desc', color: 'teal' }, - { icon: Sparkles, labelKey: 'auth.feature_ai', descKey: 'auth.feature_ai_desc', color: 'violet' }, - { icon: Heart, labelKey: 'auth.feature_collaboration', descKey: 'auth.feature_collaboration_desc', color: 'amber' }, - ]; - - const colorClasses: Record = { - emerald: { bg: 'bg-emerald-50 dark:bg-emerald-900/20', text: 'text-emerald-600 dark:text-emerald-400', border: 'border-emerald-200/60 dark:border-emerald-800/40', iconBg: 'bg-gradient-to-br from-emerald-400 to-emerald-500 text-white' }, - teal: { bg: 'bg-teal-50 dark:bg-teal-900/20', text: 'text-teal-600 dark:text-teal-400', border: 'border-teal-200/60 dark:border-teal-800/40', iconBg: 'bg-gradient-to-br from-teal-400 to-teal-500 text-white' }, - amber: { bg: 'bg-amber-50 dark:bg-amber-900/20', text: 'text-amber-600 dark:text-amber-400', border: 'border-amber-200/60 dark:border-amber-800/40', iconBg: 'bg-gradient-to-br from-amber-400 to-amber-500 text-white' }, - violet: { bg: 'bg-violet-50 dark:bg-violet-900/20', text: 'text-violet-600 dark:text-violet-400', border: 'border-violet-200/60 dark:border-violet-800/40', iconBg: 'bg-gradient-to-br from-violet-400 to-violet-500 text-white' }, - }; - - return ( - -

{t('auth.feature_showcase')}

-
- {features.map((f, i) => { - const c = colorClasses[f.color]; - return ( - -
- -
-
-

{t(f.labelKey)}

-

{t(f.descKey)}

-
-
- ); - })} -
-
- ); -} - /* ─── Main Auth View ────────────────────────────────────────── */ export default function AuthView() { const [mode, setMode] = useState<'login' | 'register'>('login'); @@ -953,57 +903,6 @@ export default function AuthView() { - {/* Social login buttons (visual only) */} - {mode === 'login' && ( - -
-
- {t('auth.or_continue_with') || 'or continue with'} -
-
-
- toast.info(t('auth.social_coming_soon') || 'Social login coming soon')} - > - - Google - - toast.info(t('auth.social_coming_soon') || 'Social login coming soon')} - > - - GitHub - - toast.info(t('auth.social_coming_soon') || 'Social login coming soon')} - > - - Moodle - -
- - )} - - {/* Features section below form */} - - {/* Footer */}