diff --git a/README.md b/README.md index d3c15f7..82dab45 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ -![GSSoC Logo](/Refixly/client/public/gssoc%20logo.png) +![GSSoC Logo](client/public/gssoc_logo.png) **🌟 Exciting News...** diff --git a/client/eslint.config.js b/client/eslint.config.js index cee1e2c..1eeb933 100644 --- a/client/eslint.config.js +++ b/client/eslint.config.js @@ -1,8 +1,8 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import { defineConfig, globalIgnores } from 'eslint/config' +import js from '@eslint/js'; +import globals from 'globals'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import { defineConfig, globalIgnores } from 'eslint/config'; export default defineConfig([ globalIgnores(['dist']), @@ -15,7 +15,12 @@ export default defineConfig([ ], languageOptions: { ecmaVersion: 2020, - globals: globals.browser, + globals: { + ...globals.browser, + ...globals.node, + ...globals.commonjs, + vi: true, + }, parserOptions: { ecmaVersion: 'latest', ecmaFeatures: { jsx: true }, @@ -26,4 +31,14 @@ export default defineConfig([ 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], }, }, -]) + { + files: ['**/test/*.js'], // Target test files specifically + languageOptions: { + globals: { + ...globals.node, + ...globals.commonjs, + vi: true, + }, + }, + }, +]); \ No newline at end of file diff --git a/client/package.json b/client/package.json index eecb0a5..d43e841 100644 --- a/client/package.json +++ b/client/package.json @@ -6,8 +6,8 @@ "scripts": { "dev": "vite", "build": "vite build", - "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", - "lint:fix": "eslint . --ext js,jsx --fix", + "lint": "eslint \"**/*.{js,jsx}\" --report-unused-disable-directives --max-warnings 0", + "lint:fix": "eslint \"**/*.{js,jsx}\" --fix", "preview": "vite preview", "test": "vitest", "test:ui": "vitest --ui", diff --git a/client/public/gssoc logo.png b/client/public/gssoc_logo.png similarity index 100% rename from client/public/gssoc logo.png rename to client/public/gssoc_logo.png diff --git a/client/src/Pages/Tutorial.jsx b/client/src/Pages/Tutorial.jsx index fbf981c..2f8dc2d 100644 --- a/client/src/Pages/Tutorial.jsx +++ b/client/src/Pages/Tutorial.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useCallback} from "react"; import NavBar from "../components/NavBar"; import { Loader, Bookmark, FileQuestion, XCircle, Filter } from "lucide-react"; import toast from "react-hot-toast"; @@ -35,7 +35,7 @@ const Tutorial = () => { setRecentlyViewed(JSON.parse(storedRecentlyViewed)); if (storedBookmarkedTutorials) setBookmarkedTutorials(JSON.parse(storedBookmarkedTutorials)); - }, []); + }, [fetchTutorials]); useEffect(() => { localStorage.setItem("searchHistory", JSON.stringify(searchHistory)); @@ -52,7 +52,7 @@ const Tutorial = () => { ); }, [bookmarkedTutorials]); - const fetchTutorials = async (objectName, pageToken = "", append = false) => { + const fetchTutorials = useCallback(async (objectName, pageToken = "", append = false) => { if (!objectName.trim()) { setError("Please enter a search term or select a category."); setTutorials([]); @@ -84,7 +84,9 @@ const Tutorial = () => { } finally { setLoading(false); } - }; + }, + [setError, setTutorials, setNextPageToken, setSearchHistory] +); const handleSearch = (e) => { e.preventDefault(); diff --git a/client/src/Pages/TutorialsPage.jsx b/client/src/Pages/TutorialsPage.jsx index 9ddc913..5002af9 100644 --- a/client/src/Pages/TutorialsPage.jsx +++ b/client/src/Pages/TutorialsPage.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback} from 'react'; import { useParams, Link } from 'react-router-dom'; import { Loader, Search, Bookmark } from 'lucide-react'; import NavBar from '../components/NavBar'; @@ -13,35 +13,59 @@ const TutorialsPage = () => { const [nextPageToken, setNextPageToken] = useState(''); const [savedTutorials, setSavedTutorials] = useState([]); - const fetchTutorials = async (loadMore = false) => { - setIsLoading(true); - setError(null); - if (!loadMore) { - setTutorials([]); + // const fetchTutorials = async (loadMore = false) => { + // setIsLoading(true); + // setError(null); + // if (!loadMore) { + // setTutorials([]); + // } + // try { + // let apiUrl = `https://refixly.onrender.com/api/tutorials/${searchTerm}`; + // if (loadMore && nextPageToken) { + // apiUrl += `?pageToken=${nextPageToken}`; + // } + // const response = await fetch(apiUrl); + // if (!response.ok) { + // throw new Error('Failed to fetch tutorials.'); + // } + // const data = await response.json(); + // setTutorials(prev => loadMore ? [...prev, ...data.tutorials] : data.tutorials); + // setNextPageToken(data.nextPageToken || ''); + // } catch (err) { + // setError(err.message); + // } finally { + // setIsLoading(false); + // } + // }; + const fetchTutorials = useCallback(async (loadMore = false) => { + setIsLoading(true); + setError(null); + if (!loadMore) { + setTutorials([]); + } + try { + let apiUrl = `https://refixly.onrender.com/api/tutorials/${searchTerm}`; + if (loadMore && nextPageToken) { + apiUrl += `?pageToken=${nextPageToken}`; } - try { - let apiUrl = `https://refixly.onrender.com/api/tutorials/${searchTerm}`; - if (loadMore && nextPageToken) { - apiUrl += `?pageToken=${nextPageToken}`; - } - const response = await fetch(apiUrl); - if (!response.ok) { - throw new Error('Failed to fetch tutorials.'); - } - const data = await response.json(); - setTutorials(prev => loadMore ? [...prev, ...data.tutorials] : data.tutorials); - setNextPageToken(data.nextPageToken || ''); - } catch (err) { - setError(err.message); - } finally { - setIsLoading(false); + const response = await fetch(apiUrl); + if (!response.ok) { + throw new Error('Failed to fetch tutorials.'); } - }; + const data = await response.json(); + setTutorials(prev => loadMore ? [...prev, ...data.tutorials] : data.tutorials); + setNextPageToken(data.nextPageToken || ''); + } catch (err) { + setError(err.message); + } finally { + setIsLoading(false); + } +}, [searchTerm, nextPageToken]); useEffect(() => { setSearchTerm(objectName); fetchTutorials(); - }, [objectName]); + }, [objectName,fetchTutorials]); const handleSearch = (e) => { e.preventDefault(); diff --git a/client/src/components/AIDamageDetection.jsx b/client/src/components/AIDamageDetection.jsx index 85d29cb..ca9c97a 100644 --- a/client/src/components/AIDamageDetection.jsx +++ b/client/src/components/AIDamageDetection.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import {useState } from "react"; import axios from "axios"; import AIResponseSection from "./AIResponseSection"; diff --git a/client/src/components/FAQAccordion.jsx b/client/src/components/FAQAccordion.jsx index 3789194..deeb26c 100644 --- a/client/src/components/FAQAccordion.jsx +++ b/client/src/components/FAQAccordion.jsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { motion, AnimatePresence } from "framer-motion"; +import { AnimatePresence } from "framer-motion"; const FAQAccordion = ({ faqs }) => { const [openIndex, setOpenIndex] = useState(null); diff --git a/client/src/components/HomeFAQ.jsx b/client/src/components/HomeFAQ.jsx index 21b16f4..4841d53 100644 --- a/client/src/components/HomeFAQ.jsx +++ b/client/src/components/HomeFAQ.jsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { motion, AnimatePresence } from "framer-motion"; +import {AnimatePresence } from "framer-motion"; const HomeFAQ = ({ faqs }) => { const [openIndex, setOpenIndex] = useState(null); diff --git a/client/src/context/ThemeContext.jsx b/client/src/context/ThemeContext.jsx index fd94690..2d07bb2 100644 --- a/client/src/context/ThemeContext.jsx +++ b/client/src/context/ThemeContext.jsx @@ -1,30 +1,4 @@ -// src/context/ThemeContext.jsx -import { createContext, useState, useEffect } from "react"; +// src/context/ThemeContext.js +import { createContext } from "react"; -export const ThemeContext = createContext(); - -export const ThemeProvider = ({ children }) => { - const [theme, setTheme] = useState("light"); - - useEffect(() => { - const savedTheme = localStorage.getItem("theme"); - if (savedTheme) setTheme(savedTheme); - }, []); - - useEffect(() => { - if (theme === "dark") { - document.documentElement.classList.add("dark"); - } else { - document.documentElement.classList.remove("dark"); - } - localStorage.setItem("theme", theme); - }, [theme]); - - const toggleTheme = () => setTheme((prev) => (prev === "light" ? "dark" : "light")); - - return ( - - {children} - - ); -}; +export const ThemeContext = createContext(); \ No newline at end of file diff --git a/client/src/context/ThemeProvider.jsx b/client/src/context/ThemeProvider.jsx new file mode 100644 index 0000000..66ee168 --- /dev/null +++ b/client/src/context/ThemeProvider.jsx @@ -0,0 +1,28 @@ +// src/context/ThemeProvider.jsx +import { useState, useEffect } from "react"; +import { ThemeContext } from "./ThemeContext.jsx"; // Import the context from the new file +export const ThemeProvider = ({ children }) => { + const [theme, setTheme] = useState("light"); + + useEffect(() => { + const savedTheme = localStorage.getItem("theme"); + if (savedTheme) setTheme(savedTheme); + }, []); + + useEffect(() => { + if (theme === "dark") { + document.documentElement.classList.add("dark"); + } else { + document.documentElement.classList.remove("dark"); + } + localStorage.setItem("theme", theme); + }, [theme]); + + const toggleTheme = () => setTheme((prev) => (prev === "light" ? "dark" : "light")); + + return ( + + {children} + + ); +}; \ No newline at end of file diff --git a/client/src/hooks/useFluidCursor.js b/client/src/hooks/useFluidCursor.js index 463e0bb..01574f4 100644 --- a/client/src/hooks/useFluidCursor.js +++ b/client/src/hooks/useFluidCursor.js @@ -235,45 +235,45 @@ const useFluidCursor = () => { } ` ); - const blurVertexShader = compileShader( - gl.VERTEX_SHADER, - ` - precision highp float; + // const blurVertexShader = compileShader( + // gl.VERTEX_SHADER, + // ` + // precision highp float; - attribute vec2 aPosition; - varying vec2 vUv; - varying vec2 vL; - varying vec2 vR; - uniform vec2 texelSize; + // attribute vec2 aPosition; + // varying vec2 vUv; + // varying vec2 vL; + // varying vec2 vR; + // uniform vec2 texelSize; - void main () { - vUv = aPosition * 0.5 + 0.5; - float offset = 1.33333333; - vL = vUv - texelSize * offset; - vR = vUv + texelSize * offset; - gl_Position = vec4(aPosition, 0.0, 1.0); - } - ` - ); - const blurShader = compileShader( - gl.FRAGMENT_SHADER, - ` - precision mediump float; - precision mediump sampler2D; + // void main () { + // vUv = aPosition * 0.5 + 0.5; + // float offset = 1.33333333; + // vL = vUv - texelSize * offset; + // vR = vUv + texelSize * offset; + // gl_Position = vec4(aPosition, 0.0, 1.0); + // } + // ` + // ); + // const blurShader = compileShader( + // gl.FRAGMENT_SHADER, + // ` + // precision mediump float; + // precision mediump sampler2D; - varying vec2 vUv; - varying vec2 vL; - varying vec2 vR; - uniform sampler2D uTexture; + // varying vec2 vUv; + // varying vec2 vL; + // varying vec2 vR; + // uniform sampler2D uTexture; - void main () { - vec4 sum = texture2D(uTexture, vUv) * 0.29411764; - sum += texture2D(uTexture, vL) * 0.35294117; - sum += texture2D(uTexture, vR) * 0.35294117; - gl_FragColor = sum; - } - ` - ); + // void main () { + // vec4 sum = texture2D(uTexture, vUv) * 0.29411764; + // sum += texture2D(uTexture, vL) * 0.35294117; + // sum += texture2D(uTexture, vR) * 0.35294117; + // gl_FragColor = sum; + // } + // ` + // ); const copyShader = compileShader( gl.FRAGMENT_SHADER, ` @@ -303,18 +303,18 @@ const useFluidCursor = () => { } ` ); - const colorShader = compileShader( - gl.FRAGMENT_SHADER, - ` - precision mediump float; + // const colorShader = compileShader( + // gl.FRAGMENT_SHADER, + // ` + // precision mediump float; - uniform vec4 color; + // uniform vec4 color; - void main () { - gl_FragColor = color; - } - ` - ); + // void main () { + // gl_FragColor = color; + // } + // ` + // ); const displayShaderSource = ` precision highp float; precision highp sampler2D; @@ -777,44 +777,44 @@ const useFluidCursor = () => { target.texelSizeY = 1.0 / h; return target; } - function createTextureAsync(url) { - let texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - gl.texImage2D( - gl.TEXTURE_2D, - 0, - gl.RGB, - 1, - 1, - 0, - gl.RGB, - gl.UNSIGNED_BYTE, - new Uint8Array([255, 255, 255]) - ); - let obj = { - texture, - width: 1, - height: 1, - attach(id) { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(gl.TEXTURE_2D, texture); - return id; - }, - }; - let image = new Image(); - image.onload = () => { - obj.width = image.width; - obj.height = image.height; - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); - }; - image.src = url; - return obj; - } + // function createTextureAsync(url) { + // let texture = gl.createTexture(); + // gl.bindTexture(gl.TEXTURE_2D, texture); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + // gl.texImage2D( + // gl.TEXTURE_2D, + // 0, + // gl.RGB, + // 1, + // 1, + // 0, + // gl.RGB, + // gl.UNSIGNED_BYTE, + // new Uint8Array([255, 255, 255]) + // ); + // let obj = { + // texture, + // width: 1, + // height: 1, + // attach(id) { + // gl.activeTexture(gl.TEXTURE0 + id); + // gl.bindTexture(gl.TEXTURE_2D, texture); + // return id; + // }, + // }; + // let image = new Image(); + // image.onload = () => { + // obj.width = image.width; + // obj.height = image.height; + // gl.bindTexture(gl.TEXTURE_2D, texture); + // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); + // }; + // image.src = url; + // return obj; + // } function updateKeywords() { let displayKeywords = []; if (config.SHADING) displayKeywords.push("SHADING");