diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 63416c8..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "next/core-web-vitals", - "rules": { - "@typescript-eslint/no-unused-vars": "warn", - "@typescript-eslint/no-explicit-any": "warn", - "react-hooks/exhaustive-deps": "warn" - } -} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index 719cea2..77619be 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,16 +1,34 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); +import nextPlugin from "@next/eslint-plugin-next"; +import reactPlugin from "eslint-plugin-react"; +import reactHooksPlugin from "eslint-plugin-react-hooks"; +import typescriptPlugin from "@typescript-eslint/eslint-plugin"; +import typescriptParser from "@typescript-eslint/parser"; const eslintConfig = [ - ...compat.extends("next/core-web-vitals", "next/typescript"), + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: typescriptParser, + globals: { + React: "readonly", + }, + }, + plugins: { + "@next/next": nextPlugin, + react: reactPlugin, + "react-hooks": reactHooksPlugin, + "@typescript-eslint": typescriptPlugin, + }, + rules: { + ...nextPlugin.configs.recommended.rules, + ...reactPlugin.configs.recommended.rules, + ...reactHooksPlugin.configs.recommended.rules, + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "@typescript-eslint/no-unused-vars": "warn", + }, + }, { ignores: [ "node_modules/**", diff --git a/next.config.js b/next.config.js index eaacc0e..9422530 100644 --- a/next.config.js +++ b/next.config.js @@ -6,14 +6,6 @@ const nextConfig = { eslint: { ignoreDuringBuilds: false, }, - // Skip linting during build to speed up deployment - eslint: { - ignoreDuringBuilds: true, - }, - // Skip type checking during build - typescript: { - ignoreBuildErrors: true, - }, } -module.exports = nextConfig \ No newline at end of file +module.exports = nextConfig diff --git a/package-lock.json b/package-lock.json index bd5d57d..f3f1f15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "skillsync", "version": "1.0.0", "dependencies": { + "@ai-sdk/openai": "^0.0.33", "@auth/prisma-adapter": "^2.11.0", "@hookform/resolvers": "^3.3.0", "@next-auth/prisma-adapter": "^1.0.7", @@ -54,6 +55,75 @@ "typescript": "^5.0.0" } }, + "node_modules/@ai-sdk/openai": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-0.0.33.tgz", + "integrity": "sha512-siVeHnagh08UFgdwflPdUKTdrVvfU/JWqSa8nCsMy6DvSri8T7zTzPZoCxXiMKPXkhQDd/KsaXhweOShGLQ1uQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "0.0.10", + "@ai-sdk/provider-utils": "0.0.16" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.0.0" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-0.0.10.tgz", + "integrity": "sha512-NzkrtREQpHID1cTqY/C4CI30PVOaXWKYytDR2EcytmFgnP7Z6+CrGIA/YCnNhYAuUm6Nx+nGpRL/Hmyrv7NYzg==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-0.0.16.tgz", + "integrity": "sha512-W2zUZ+C5uDr2P9/KZwtV4r4F0l2RlD0AvtJyug7ER5g3hGHAfKrPM0y2hSlRxNfph5BTCC6YQX0nFLyBph+6bQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "0.0.10", + "eventsource-parser": "1.1.2", + "nanoid": "3.3.6", + "secure-json-parse": "2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@ai-sdk/provider-utils/node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "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/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -131,6 +201,7 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -1031,6 +1102,7 @@ "integrity": "sha512-zL58jbLzYamjnNnmNA51IOZdbk5ci03KviXCuB0Tydc9btH2kDWsi1pQm2VecviRTM7jGia0OPPkgpGnT3nKvw==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18" }, @@ -2307,6 +2379,7 @@ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -2318,6 +2391,7 @@ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -2368,6 +2442,7 @@ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", @@ -2892,6 +2967,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3340,6 +3416,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -4326,6 +4403,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4495,6 +4573,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -4799,6 +4878,15 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/eventsource-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.1.2.tgz", + "integrity": "sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==", + "license": "MIT", + "engines": { + "node": ">=14.18" + } + }, "node_modules/exsolve": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", @@ -6055,6 +6143,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6705,6 +6799,7 @@ "resolved": "https://registry.npmjs.org/next/-/next-15.0.0.tgz", "integrity": "sha512-/ivqF6gCShXpKwY9hfrIQYh8YMge8L3W+w1oRLv/POmK4MOQnh+FscZ8a0fRFTSQWE+2z9ctNYvELD9vP2FV+A==", "license": "MIT", + "peer": true, "dependencies": { "@next/env": "15.0.0", "@swc/counter": "0.1.3", @@ -6759,6 +6854,7 @@ "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.11.tgz", "integrity": "sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==", "license": "ISC", + "peer": true, "dependencies": { "@babel/runtime": "^7.20.13", "@panva/hkdf": "^1.0.2", @@ -7313,6 +7409,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7461,6 +7558,7 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -7500,6 +7598,7 @@ "integrity": "sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@prisma/config": "6.17.1", "@prisma/engines": "6.17.1" @@ -7576,6 +7675,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -7588,6 +7688,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -7601,6 +7702,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.65.0.tgz", "integrity": "sha512-xtOzDz063WcXvGWaHgLNrNzlsdFgtUWcb32E6WFaGTd7kPZG3EeDusjdZfUsPwKCKVXy1ZlntifaHZ4l8pAsmw==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -8022,6 +8124,12 @@ "loose-envify": "^1.1.0" } }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -8868,6 +8976,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -9024,6 +9133,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9459,6 +9569,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 662120d..f5d3da4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dev": "next dev", "build": "prisma generate && next build", "start": "next start", - "lint": "next lint", + "lint": "eslint .", "db:push": "prisma db push", "db:studio": "prisma studio", "db:generate": "prisma generate" @@ -40,7 +40,8 @@ "recharts": "^2.8.0", "sonner": "^1.0.0", "tailwind-merge": "^2.0.0", - "zod": "^3.22.0" + "zod": "^3.22.0", + "@ai-sdk/openai": "^0.0.33" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.14", diff --git a/src/app/api/chat/route.ts b/src/app/api/chat/route.ts index c71b664..fc546cf 100644 --- a/src/app/api/chat/route.ts +++ b/src/app/api/chat/route.ts @@ -1,3 +1,4 @@ + import { aiService } from '@/lib/ai-service' export async function POST(req: Request) { @@ -8,7 +9,7 @@ export async function POST(req: Request) { const lastMessage = messages[messages.length - 1]?.content || 'Hello' // Generate response using our local AI service - const response = aiService.generateChatResponse(lastMessage) + const response = await aiService.generateChatResponse(lastMessage) return new Response( JSON.stringify({ @@ -29,18 +30,12 @@ export async function POST(req: Request) { return new Response( JSON.stringify({ - id: Date.now().toString(), - choices: [{ - message: { - role: 'assistant', - content: "I'm here to help you with SkillSync! You can browse skills, create learning modules, or connect with our community. How can I assist you today?" - } - }] + error: 'An error occurred while processing your request.' }), { - status: 200, + status: 500, headers: { 'Content-Type': 'application/json' }, } ) } -} \ No newline at end of file +} diff --git a/src/app/auth/error/page.tsx b/src/app/auth/error/page.tsx index d5e2878..ad22a8f 100644 --- a/src/app/auth/error/page.tsx +++ b/src/app/auth/error/page.tsx @@ -1,5 +1,4 @@ import { Suspense } from 'react'; -import Link from 'next/link'; import { ErrorContent } from './error-content'; export default function AuthErrorPage() { diff --git a/src/app/auth/signin/page.tsx b/src/app/auth/signin/page.tsx index d3e395f..3ee7fc3 100644 --- a/src/app/auth/signin/page.tsx +++ b/src/app/auth/signin/page.tsx @@ -1,7 +1,7 @@ 'use client' import { useState } from 'react' -import { signIn, getSession } from 'next-auth/react' +import { signIn } from 'next-auth/react' import { useRouter } from 'next/navigation' import Link from 'next/link' import { Button } from '@/components/ui/button' @@ -31,7 +31,7 @@ export default function SignIn() { } else { router.push('/dashboard') } - } catch (error) { + } catch { alert('An error occurred') } finally { setLoading(false) @@ -145,7 +145,7 @@ export default function SignIn() { {/* Sign Up Link */}
- Don't have an account?{' '} + Don't have an account?{' '} Sign up diff --git a/src/app/auth/signup/page.tsx b/src/app/auth/signup/page.tsx index de6ba90..9539485 100644 --- a/src/app/auth/signup/page.tsx +++ b/src/app/auth/signup/page.tsx @@ -34,7 +34,7 @@ export default function SignUp() { } else { router.push('/dashboard') } - } catch (error) { + } catch { alert('An error occurred') } finally { setLoading(false) diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index d590eee..cb7ddba 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -125,7 +125,7 @@ export default function Dashboard() { Ready to Start Your Learning Journey, {getFirstName()}?
- Your dashboard is where you'll track your progress, manage your skills, and connect with other learners. + Your dashboard is where you'll track your progress, manage your skills, and connect with other learners.