From ed6692e05e0fae0deb7c84c66a764d43b5763ce7 Mon Sep 17 00:00:00 2001 From: agricreations Date: Fri, 19 Apr 2024 22:29:06 +0530 Subject: [PATCH 1/5] Implementing jwt authorisations --- backend/app.js | 2 + backend/controller/github-oauth.controller.js | 89 +++++++++++++++++- backend/package-lock.json | 90 ++++++++++--------- backend/package.json | 6 +- backend/routes/github-oauth.router.js | 38 +------- ui/src/hooks/useGitHubAuthentication.js | 3 +- ui_tailwind_shadecn/src/App.tsx | 2 + .../src/api/components/components.tsx | 2 +- .../src/components/ui/commandMenu.tsx | 45 ++++++---- ui_tailwind_shadecn/src/screens/Login.tsx | 52 +++++++++++ 10 files changed, 234 insertions(+), 95 deletions(-) create mode 100644 ui_tailwind_shadecn/src/screens/Login.tsx diff --git a/backend/app.js b/backend/app.js index e121ba5..0d7a1e7 100644 --- a/backend/app.js +++ b/backend/app.js @@ -9,6 +9,7 @@ const path = require('path'); //path const session = require('express-session'); require('dotenv').config(); + // json webtokens const jwt = require('jsonwebtoken') @@ -29,6 +30,7 @@ const app = express(); const port = 4000; app.use(cors()); app.use(express.json()); + // app.use(bodyParser.json()); //importing router files diff --git a/backend/controller/github-oauth.controller.js b/backend/controller/github-oauth.controller.js index be778a2..571103a 100644 --- a/backend/controller/github-oauth.controller.js +++ b/backend/controller/github-oauth.controller.js @@ -2,11 +2,17 @@ const axios = require('axios'); const GitHubUser = require('../models/user.model'); require('dotenv').config(); +const jwt = require('jsonwebtoken'); const {jsonStatus, jsonStatusError, jsonStatusSuccess} = require('../operations/errorhandlingOperations'); +const {getUserInformationsByName} = require('../controller/userProfile.controller'); +const { response } = require('express'); + +const JWT_SECRET = process.env.JWT_ACCESS_TOKEN; async function exchangeGitHubCodeForToken(code) { const client_id = process.env.GITHUB_CLIENT_ID; const client_secret = process.env.GITHUB_CLIENT_SECRET; + console.log(client_secret); const params = `?client_id=${client_id}&client_secret=${client_secret}&code=${code}`; try { const response = await axios.post( @@ -70,5 +76,86 @@ const getUserInfoFromGit = async (req, res) => { } }; -module.exports = { exchangeGitHubCodeForToken , getUserInformationsFromGitApi, getUserInfoFromGit}; +const signup_or_login_with_git = async (req,res)=>{ + + // it will create a new account if account not already existis or creates a new account + + const { code } = req.body; + try { + // #TODO Upadate a auth token where authanticated by user + const githubAccessToken = await exchangeGitHubCodeForToken(code); + + const userInformations = await getUserInformationsFromGitApi(githubAccessToken); + + //get user profile info with github oauth + const gitUserId = userInformations.id; + const existingUser = await GitHubUser.findOne({ id: gitUserId }); + + // #TODO test if not an existing user (Test the app behaviour) and update the code (high priyority) + if (!existingUser) { + const githubUser = new GitHubUser(userInformations); + await githubUser.save(); + const response ={ + "token": createTokens({userId: githubUser.id, userName: githubUser.name}), + "user": githubUser, + "components": [] + } + return res.json(jsonStatusSuccess({ message: `New Account created ${githubUser.name}`, response: response })); + } + + getUserInformationsByName(existingUser.name, async (error, userProfileWithComponents) => { + if (error) { + return res.status(500).send(`Internal Server Error ${error}`); + } else { + userProfileWithComponents['token'] = createTokens({userId: existingUser.id, userName: existingUser.name}); + return res.json(jsonStatusSuccess({ message: `Welcome Back ${existingUser.name}`, response: await userProfileWithComponents })); + + // res.json({ success: true, githubAccessToken: await req.session.githubAccessToken, token: githubAccessToken, response: await userProfileWithComponents}); + } + }); + // req.session.githubAccessToken = await githubAccessToken; + + } catch (error) { + console.error('Error during GitHub OAuth:', error); + res.status(500).json({ success: false, error: error }); + } +} + +const createTokens = (tokenProperties)=>{ + // Assume user is authenticated via GitHub and obtain user info + // const { userId, username } = req.body; + + // Create JWT token + const token = jwt.sign({ tokenProperties }, JWT_SECRET, { expiresIn: '1h' }); + + // Set HTTPOnly cookie with JWT token + // res.cookie('jwt', token, { httpOnly: true, secure: true }); + + return token; +} + +const validateToken = (req,res)=>{ + // Retrieve JWT token from cookie + // const token = req.cookies.jwt; + const { token } = req.body; + + if (!token) { + return res.status(401).json({ message: 'Unauthorized' }); + } + + try { + // Verify JWT token + const decoded = jwt.verify(token, JWT_SECRET); + console.log(decoded); + + // Access protected resource + res.status(200).json({ message: 'Token validated', user: decoded }); + } catch (err) { + // Token verification failed + res.status(401).json({ message: 'Unauthorized' }); + } +} + + +module.exports = { exchangeGitHubCodeForToken , getUserInformationsFromGitApi, getUserInfoFromGit, createTokens, validateToken, signup_or_login_with_git}; diff --git a/backend/package-lock.json b/backend/package-lock.json index 895116a..da59700 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,14 +14,16 @@ "cors": "^2.8.5", "discord.js": "^14.12.1", "dotenv": "^16.3.1", - "express": "^4.18.2", + "express": "^4.19.2", + "express-jwt": "^8.4.1", "express-openid-connect": "^2.17.1", "express-session": "^1.17.3", "jsonwebtoken": "^9.0.2", "mongoose": "^8.1.0", "node-telegram-bot-api": "^0.63.0", "passport": "^0.7.0", - "passport-github": "^1.1.0" + "passport-github": "^1.1.0", + "passport-github2": "^0.1.12" }, "devDependencies": { "nodemon": "^3.1.0" @@ -248,6 +250,14 @@ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -1062,16 +1072,16 @@ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -1102,6 +1112,19 @@ "node": ">= 0.10.0" } }, + "node_modules/express-jwt": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-8.4.1.tgz", + "integrity": "sha512-IZoZiDv2yZJAb3QrbaSATVtTCYT11OcqgFGoTN4iKVyN6NBkBkhtVIixww5fmakF0Upt5HfOxJuS6ZmJVeOtTQ==", + "dependencies": { + "@types/jsonwebtoken": "^9", + "express-unless": "^2.1.3", + "jsonwebtoken": "^9.0.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/express-openid-connect": { "version": "2.17.1", "resolved": "https://registry.npmjs.org/express-openid-connect/-/express-openid-connect-2.17.1.tgz", @@ -1204,41 +1227,17 @@ "node": ">= 0.6" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } + "node_modules/express-unless": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-2.1.3.tgz", + "integrity": "sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ==" }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/extend": { @@ -2654,6 +2653,17 @@ "node": ">= 0.4.0" } }, + "node_modules/passport-github2": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/passport-github2/-/passport-github2-0.1.12.tgz", + "integrity": "sha512-3nPUCc7ttF/3HSP/k9sAXjz3SkGv5Nki84I05kSQPo01Jqq1NzJACgMblCK0fGcv9pKCG/KXU3AJRDGLqHLoIw==", + "dependencies": { + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/passport-oauth2": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", diff --git a/backend/package.json b/backend/package.json index 058f94f..35b74d4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -15,14 +15,16 @@ "cors": "^2.8.5", "discord.js": "^14.12.1", "dotenv": "^16.3.1", - "express": "^4.18.2", + "express": "^4.19.2", + "express-jwt": "^8.4.1", "express-openid-connect": "^2.17.1", "express-session": "^1.17.3", "jsonwebtoken": "^9.0.2", "mongoose": "^8.1.0", "node-telegram-bot-api": "^0.63.0", "passport": "^0.7.0", - "passport-github": "^1.1.0" + "passport-github": "^1.1.0", + "passport-github2": "^0.1.12" }, "devDependencies": { "nodemon": "^3.1.0" diff --git a/backend/routes/github-oauth.router.js b/backend/routes/github-oauth.router.js index 32a0003..88866f4 100644 --- a/backend/routes/github-oauth.router.js +++ b/backend/routes/github-oauth.router.js @@ -1,11 +1,10 @@ // authRouter.js const express = require('express'); const axios = require('axios'); -const { exchangeGitHubCodeForToken, getUserInfoFromGit, getUserInformationsFromGitApi } = require('../controller/github-oauth.controller'); +const { exchangeGitHubCodeForToken, getUserInfoFromGit, getUserInformationsFromGitApi, createTokens, validateToken, signup_or_login_with_git } = require('../controller/github-oauth.controller'); const authRouter = express.Router(); require('dotenv').config(); const GitHubUser = require('../models/user.model'); -const {getUserInformationsByName} = require('../controller/userProfile.controller'); authRouter.get('/', (req, res) => { res.send('welcome to git') @@ -14,39 +13,10 @@ authRouter.get('/', (req, res) => { authRouter.post('/getUserInfoFromGit', getUserInfoFromGit); // #TODO upgrade this with proper session -authRouter.post('/github-oauth', async (req, res) => { - const { code } = req.body; - try { - // #TODO Upadate a auth token where authanticated by user - // const githubAccessToken = await exchangeGitHubCodeForToken(code); - const githubAccessToken = "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"; - console.log(`Git access token ${githubAccessToken}`); +authRouter.post('/github-oauth', signup_or_login_with_git); - const userInformations = await getUserInformationsFromGitApi(githubAccessToken); +authRouter.post('/github', createTokens ) - //get user profile info with github oauth - const gitUserId = userInformations.id; - const existingUser = await GitHubUser.findOne({ id: gitUserId }); - - // #TODO test if not an existing user (Test the app behaviour) and update the code (high priyority) - if (!existingUser) { - const githubUser = new GitHubUser(userInformations); - await githubUser.save(); - } - - getUserInformationsByName(existingUser.name, async (error, userProfileWithComponents) => { - if (error) { - return res.status(500).send(`Internal Server Error ${error}`); - } else { - res.json({ success: true, githubAccessToken: await req.session.githubAccessToken, token: githubAccessToken, response: await userProfileWithComponents}); - } - }); - // req.session.githubAccessToken = await githubAccessToken; - - } catch (error) { - console.error('Error during GitHub OAuth:', error); - res.status(500).json({ success: false, error: error }); - } -}); +authRouter.post('/github-validate', validateToken ) module.exports = { authRouter }; diff --git a/ui/src/hooks/useGitHubAuthentication.js b/ui/src/hooks/useGitHubAuthentication.js index adaf2a3..20b6ff7 100644 --- a/ui/src/hooks/useGitHubAuthentication.js +++ b/ui/src/hooks/useGitHubAuthentication.js @@ -13,6 +13,8 @@ const useGitHubAuthentication = () => { setIsLoggedIn(true); } }, []); + + // https://github.com/login/oauth/authorize?client_id=5871c78bb36c12b03eb3&redirect_uri=http://localhost:5174/&scope=user const handleLogin = () => { const urlParams = new URLSearchParams(window.location.search); @@ -23,7 +25,6 @@ const useGitHubAuthentication = () => { const scope = 'user'; const state = generateRandomState(); const githubOAuthUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}`; - const authWindow = window.open(githubOAuthUrl, '_blank'); fetch('http://localhost:4000/auth/github-oauth', { diff --git a/ui_tailwind_shadecn/src/App.tsx b/ui_tailwind_shadecn/src/App.tsx index 0016904..d99f649 100644 --- a/ui_tailwind_shadecn/src/App.tsx +++ b/ui_tailwind_shadecn/src/App.tsx @@ -13,6 +13,7 @@ import SettingsAppearancePage from '@/screens/settings/appearance/page' import SettingsDisplayPage from '@/screens/settings/display/page' import SettingsLayout from '@/screens/settings/layout' import AboutUs from '@/screens/AboutUs'; +import { Login } from './screens/Login'; function App() { @@ -37,6 +38,7 @@ function App() { } />} /> } /> + } /> diff --git a/ui_tailwind_shadecn/src/api/components/components.tsx b/ui_tailwind_shadecn/src/api/components/components.tsx index 6e8513a..7d873b6 100644 --- a/ui_tailwind_shadecn/src/api/components/components.tsx +++ b/ui_tailwind_shadecn/src/api/components/components.tsx @@ -10,7 +10,7 @@ type ResponseItem = { export const fetchComponentsStore = async (categories: string) => { const baseUri = getEnvVariable('BASE_URI'); try { - const response = await fetch(`${baseUri}/components/searchcomponents?search=${categories}`); + const response = await fetch(`${baseUri}/components/latest?category=${categories}`); if (!response.ok) { throw new Error('Failed to fetch categories'); } diff --git a/ui_tailwind_shadecn/src/components/ui/commandMenu.tsx b/ui_tailwind_shadecn/src/components/ui/commandMenu.tsx index 197776b..5aca2ca 100644 --- a/ui_tailwind_shadecn/src/components/ui/commandMenu.tsx +++ b/ui_tailwind_shadecn/src/components/ui/commandMenu.tsx @@ -1,11 +1,9 @@ import * as React from "react" import { - Calculator, - Calendar, CreditCard, + Layers, Settings, - Smile, User, } from "lucide-react" @@ -20,6 +18,10 @@ import { CommandShortcut, } from "@/components/ui/command" +import { useCategoriesStore } from '@/store/store'; +import { Skeleton } from "./skeleton"; +import { Link } from "react-router-dom"; + export function CommandDialogDemo() { const [open, setOpen] = React.useState(false) @@ -35,6 +37,8 @@ export function CommandDialogDemo() { return () => document.removeEventListener("keydown", down) }, []) + const categries = useCategoriesStore((state) => state.categories); + return ( <>

@@ -47,20 +51,29 @@ export function CommandDialogDemo() { No results found. - - - - Calendar - - - - Search Emoji - - - - Calculator - + + + {categries.length > 0 ? ( + categries.map((category, index) => ( +

+ + + + {category} + + +
+ )) + ) : ( + <> + + + )} + + diff --git a/ui_tailwind_shadecn/src/screens/Login.tsx b/ui_tailwind_shadecn/src/screens/Login.tsx new file mode 100644 index 0000000..f6e7307 --- /dev/null +++ b/ui_tailwind_shadecn/src/screens/Login.tsx @@ -0,0 +1,52 @@ + +import { MovingButton } from "@/components/ui/moving-border" +import { Checkbox } from "@/components/ui/checkbox" +import MainNav from "@/components/custom_ui/MainNav" + + +export function Login() { + return ( + <> + < MainNav/> +
+
+
+
+

Login or Signup

+

+ Create Your Account with github +

+
+
+ + +
+
+ + Signup With Github + +
+
+
+
+ Image +
+
+ + ) +} From 881fd4eae667db499b6b01839a9c9d4640702921 Mon Sep 17 00:00:00 2001 From: agricreations Date: Sun, 21 Apr 2024 07:48:03 +0530 Subject: [PATCH 2/5] adding logto to docker development --- docker-compose.yaml | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index a1b14cd..5e1658a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -39,10 +39,54 @@ services: networks: my_network: ipv4_address: 172.28.0.3 + + adminer: + image: adminer + container_name: my_adminer + restart: always + ports: + - "8080:8080" + + postgres: + image: postgres:latest + container_name: my_postgres_db + restart: always + environment: + POSTGRES_DB: my_database + POSTGRES_USER: my_user + POSTGRES_PASSWORD: my_password + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + + logto: + depends_on: + postgres: + condition: service_healthy + image: svhd/logto:${TAG-latest} + entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"] + ports: + - "3001:3001" # Map container port 3001 to host port 3001 + - "3002:3002" # Map container port 3002 to host port 3002 + environment: + - TRUST_PROXY_HEADER=1 + # Use localhost instead of the service name for local testing + - DB_URL=postgres://my_user:my_password@postgres:5432/logto + # Set other environment variables as needed + - ENDPOINT + - ADMIN_ENDPOINT + volumes: mongodb_data: redis_data: + postgres_data: networks: my_network: From dd10c8657e590d04d48181e665f12beed2c66efa Mon Sep 17 00:00:00 2001 From: agricreations Date: Sun, 21 Apr 2024 17:47:16 +0530 Subject: [PATCH 3/5] Front Github Oauth implementations --- ui_tailwind_shadecn/src/App.tsx | 53 ++++++++++++++----- .../src/hooks/handle_login.hooks.tsx | 13 +++++ .../src/screens/{ => Auth}/Login.tsx | 16 +++++- .../src/screens/Auth/Signup.tsx | 0 .../src/screens/Components.tsx | 5 +- ui_tailwind_shadecn/src/store/Auth.tsx | 22 ++++++++ .../src/types/LoginStore.type.tsx | 19 +++++++ 7 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 ui_tailwind_shadecn/src/hooks/handle_login.hooks.tsx rename ui_tailwind_shadecn/src/screens/{ => Auth}/Login.tsx (80%) create mode 100644 ui_tailwind_shadecn/src/screens/Auth/Signup.tsx create mode 100644 ui_tailwind_shadecn/src/store/Auth.tsx create mode 100644 ui_tailwind_shadecn/src/types/LoginStore.type.tsx diff --git a/ui_tailwind_shadecn/src/App.tsx b/ui_tailwind_shadecn/src/App.tsx index d99f649..e20cfb8 100644 --- a/ui_tailwind_shadecn/src/App.tsx +++ b/ui_tailwind_shadecn/src/App.tsx @@ -1,26 +1,55 @@ import './App.css' import '../app/globals.css' import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; -import {Dashboard} from './screens/Home'; +import { Dashboard } from './screens/Home'; import Testing from './screens/Testing'; -import {Components} from './screens/Components'; +import { Components } from './screens/Components'; import { View } from '@/screens/View'; // import { Settings } from '@/screens/Settings'; -import SettingsProfilePage from '@/screens/settings/page' -import SettingsAccountPage from '@/screens/settings/account/page' -import SettingsNotificationsPage from '@/screens/settings/notifications/page' -import SettingsAppearancePage from '@/screens/settings/appearance/page' -import SettingsDisplayPage from '@/screens/settings/display/page' -import SettingsLayout from '@/screens/settings/layout' +import SettingsProfilePage from '@/screens/settings/page' +import SettingsAccountPage from '@/screens/settings/account/page' +import SettingsNotificationsPage from '@/screens/settings/notifications/page' +import SettingsAppearancePage from '@/screens/settings/appearance/page' +import SettingsDisplayPage from '@/screens/settings/display/page' +import SettingsLayout from '@/screens/settings/layout' import AboutUs from '@/screens/AboutUs'; -import { Login } from './screens/Login'; +import { Login } from './screens/Auth/Login'; +import { useEffect } from 'react'; +import {useLoginStore} from "@/store/Auth" function App() { + const urlParams = new URLSearchParams(window.location.search); + const code = urlParams.get('code'); - return ( + useEffect(() => { + if(code){ + fetch('http://localhost:4000/auth/github-oauth', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ code }), + }) + .then(response => response.json()) + .then(data => { + if(data.error == false){ + useLoginStore.setState({isLogin: true}); + } + window.localStorage.setItem('githubOAuthState', data.response.user); + window.localStorage.setItem('user', data.response.user.id); + window.localStorage.setItem('token', data.response.token); + + }) + .catch(error => { + console.error('GitHub authentication error:', error); + }); + } + }, [code]) + + return ( <> - + } /> } /> @@ -36,7 +65,7 @@ function App() { } />} /> } />} /> - } />} /> + } />} /> } /> } /> diff --git a/ui_tailwind_shadecn/src/hooks/handle_login.hooks.tsx b/ui_tailwind_shadecn/src/hooks/handle_login.hooks.tsx new file mode 100644 index 0000000..ad410eb --- /dev/null +++ b/ui_tailwind_shadecn/src/hooks/handle_login.hooks.tsx @@ -0,0 +1,13 @@ + +export const HandleLogin = () => { + + const clientId = '5871c78bb36c12b03eb3'; + const redirectUri = 'http://localhost:5174'; + const scope = 'user'; + const githubOAuthUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}`; + + window.location.href = githubOAuthUrl + + + + }; \ No newline at end of file diff --git a/ui_tailwind_shadecn/src/screens/Login.tsx b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx similarity index 80% rename from ui_tailwind_shadecn/src/screens/Login.tsx rename to ui_tailwind_shadecn/src/screens/Auth/Login.tsx index f6e7307..da7a343 100644 --- a/ui_tailwind_shadecn/src/screens/Login.tsx +++ b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx @@ -2,9 +2,22 @@ import { MovingButton } from "@/components/ui/moving-border" import { Checkbox } from "@/components/ui/checkbox" import MainNav from "@/components/custom_ui/MainNav" - +import { useLocation } from 'react-router-dom'; +import { useEffect } from "react"; +import {HandleLogin} from '@/hooks/handle_login.hooks'; export function Login() { + + const location = useLocation(); + useEffect(() => { + // Parse the query string to get the value of the 'code' parameter + const params = new URLSearchParams(location.search); + const code = params.get('code'); + + // Do something with the 'code' value, like sending it to the server for authentication + console.log('Code:', code); + }, [location.search]); + return ( <> < MainNav/> @@ -31,6 +44,7 @@ export function Login() { duration={3000} borderRadius="10px" className="p-1 mr-3" + onClick={HandleLogin} > Signup With Github diff --git a/ui_tailwind_shadecn/src/screens/Auth/Signup.tsx b/ui_tailwind_shadecn/src/screens/Auth/Signup.tsx new file mode 100644 index 0000000..e69de29 diff --git a/ui_tailwind_shadecn/src/screens/Components.tsx b/ui_tailwind_shadecn/src/screens/Components.tsx index 06acfae..ab8fb40 100644 --- a/ui_tailwind_shadecn/src/screens/Components.tsx +++ b/ui_tailwind_shadecn/src/screens/Components.tsx @@ -29,6 +29,7 @@ import { Logo } from "@/components/custom_ui/Svg" import OutputsOfComponents from "@/components/custom_ui/OutputComponents" import { ComponentType } from "@/enums/iframEnums" import { useCategoriesStore, useComponentsStore } from "@/store/store" +import {useLoginStore} from "@/store/Auth" import {ComponentsStore, } from '@/types/ComponentStore.type' import { useEffect } from "react" import { fetchCategories } from "@/api/components/categories" @@ -50,7 +51,8 @@ export function Components() { // this categries getting from a zustand store const categries = useCategoriesStore((state) => state.categories); const components = useComponentsStore((state) => state[catogries as keyof ComponentsStore] ?? 'all'); - console.log(components); + const user = useLoginStore((state)=> state.user); + // useLoginStore.setState({isLogin: true}); useEffect(() => { fetchCategories(); @@ -184,6 +186,7 @@ export function Components() {

{catogries} Components

+

{user ? user.name : "please login"}

diff --git a/ui_tailwind_shadecn/src/store/Auth.tsx b/ui_tailwind_shadecn/src/store/Auth.tsx new file mode 100644 index 0000000..5de47ff --- /dev/null +++ b/ui_tailwind_shadecn/src/store/Auth.tsx @@ -0,0 +1,22 @@ +import { LoginStore } from '@/types/LoginStore.type'; +import { create } from 'zustand'; + +export const useLoginStore = create(() => ({ + isLogin: false, + user: { + _id: "", + id: null, + login: null, + avatar_url: null, + url: null, + html_url: null, + company: null, + location: null, + email: null, + name: null, + blog: null, + bio: null, + twitter_username: null, + __v: 0 + } +})); diff --git a/ui_tailwind_shadecn/src/types/LoginStore.type.tsx b/ui_tailwind_shadecn/src/types/LoginStore.type.tsx new file mode 100644 index 0000000..508cefd --- /dev/null +++ b/ui_tailwind_shadecn/src/types/LoginStore.type.tsx @@ -0,0 +1,19 @@ +export type LoginStore = { + isLogin: boolean; + user: { + _id: string; + id: number | null; + login: string | null; + avatar_url: string | null; + url: string | null; + html_url: string | null; + company: string | null; + location: string | null; + email: string | null; + name: string | null; + blog: string | null; + bio: string | null; + twitter_username: string | null; + __v: number; + } +}; From 3aa5878bd3928e589b96bb4e4599da0bdd1515db Mon Sep 17 00:00:00 2001 From: agricreations Date: Mon, 22 Apr 2024 22:17:38 +0530 Subject: [PATCH 4/5] upating nabar --- ui_tailwind_shadecn/src/App.tsx | 9 +- .../custom_ui/{ => NavBar}/MainNav.tsx | 69 +++--- .../custom_ui/NavBar/NavProfile.tsx | 64 ++++++ ui_tailwind_shadecn/src/screens/AboutUs.tsx | 2 +- .../src/screens/Auth/Login.tsx | 2 +- .../src/screens/Components.tsx | 44 +--- ui_tailwind_shadecn/src/screens/Home.tsx | 2 +- .../src/screens/Profile/Profile.tsx | 213 ++++++++++++++++++ .../src/screens/settings/layout.tsx | 2 +- ui_tailwind_shadecn/src/store/Auth.tsx | 38 ++-- .../src/types/LoginStore.type.tsx | 7 +- 11 files changed, 349 insertions(+), 103 deletions(-) rename ui_tailwind_shadecn/src/components/custom_ui/{ => NavBar}/MainNav.tsx (80%) create mode 100644 ui_tailwind_shadecn/src/components/custom_ui/NavBar/NavProfile.tsx create mode 100644 ui_tailwind_shadecn/src/screens/Profile/Profile.tsx diff --git a/ui_tailwind_shadecn/src/App.tsx b/ui_tailwind_shadecn/src/App.tsx index e20cfb8..cfd40fc 100644 --- a/ui_tailwind_shadecn/src/App.tsx +++ b/ui_tailwind_shadecn/src/App.tsx @@ -13,9 +13,10 @@ import SettingsAppearancePage from '@/screens/settings/appearance/page' import SettingsDisplayPage from '@/screens/settings/display/page' import SettingsLayout from '@/screens/settings/layout' import AboutUs from '@/screens/AboutUs'; -import { Login } from './screens/Auth/Login'; +import { Login } from '@/screens/Auth/Login'; import { useEffect } from 'react'; -import {useLoginStore} from "@/store/Auth" +import { useLoginStore, useLoginUserInfo } from "@/store/Auth" +import { Profile } from './screens/Profile/Profile'; function App() { const urlParams = new URLSearchParams(window.location.search); @@ -38,7 +39,8 @@ function App() { window.localStorage.setItem('githubOAuthState', data.response.user); window.localStorage.setItem('user', data.response.user.id); window.localStorage.setItem('token', data.response.token); - + useLoginStore.setState({isLogin: true}); + useLoginUserInfo.setState(data.response.user) }) .catch(error => { console.error('GitHub authentication error:', error); @@ -68,6 +70,7 @@ function App() { } />} /> } /> } /> + } /> diff --git a/ui_tailwind_shadecn/src/components/custom_ui/MainNav.tsx b/ui_tailwind_shadecn/src/components/custom_ui/NavBar/MainNav.tsx similarity index 80% rename from ui_tailwind_shadecn/src/components/custom_ui/MainNav.tsx rename to ui_tailwind_shadecn/src/components/custom_ui/NavBar/MainNav.tsx index 41315f9..963f24b 100644 --- a/ui_tailwind_shadecn/src/components/custom_ui/MainNav.tsx +++ b/ui_tailwind_shadecn/src/components/custom_ui/NavBar/MainNav.tsx @@ -11,7 +11,6 @@ import { } from "@/components/ui/navigation-menu" import { - CircleUser, Menu, Search } from "lucide-react" @@ -20,8 +19,6 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" @@ -32,12 +29,18 @@ import { Link } from "react-router-dom" import { Input } from "@/components/ui/input" import { Logo } from "@/components/custom_ui/Svg" -import { Button } from "../ui/button" +import { Button } from "../../ui/button" +import { NavProfile } from "./NavProfile" +// import { useLoginStore, useLoginUserInfo } from "@/store/Auth" -export default function MainNav(){ + +export default function MainNav() { const { setTheme } = useTheme() + // const user = useLoginStore((state) => state.isLogin); + // const userInfo = useLoginUserInfo((state) => state); + return ( <> @@ -123,23 +126,23 @@ export default function MainNav(){ @@ -174,26 +177,8 @@ export default function MainNav(){ - - - - - - My Account - - - - Settings - - - Support - - Logout - - + + diff --git a/ui_tailwind_shadecn/src/components/custom_ui/NavBar/NavProfile.tsx b/ui_tailwind_shadecn/src/components/custom_ui/NavBar/NavProfile.tsx new file mode 100644 index 0000000..ed7f965 --- /dev/null +++ b/ui_tailwind_shadecn/src/components/custom_ui/NavBar/NavProfile.tsx @@ -0,0 +1,64 @@ +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" + +import { + CircleUser +} from "lucide-react" +import { Button } from "../../ui/button" +import { useLoginStore, useLoginUserInfo } from "@/store/Auth" +import { Link } from "react-router-dom" + +export const NavProfile = ()=>{ + const user = useLoginStore((state) => state.isLogin); + const userInfo = useLoginUserInfo((state) => state); + return( + <> + + + + + + Info + + { + user ? + + + {userInfo.name} + + + : <> + } + + + Settings + + + + + + {user ? "Logout" : "Login"} + + + + + + + ) +} \ No newline at end of file diff --git a/ui_tailwind_shadecn/src/screens/AboutUs.tsx b/ui_tailwind_shadecn/src/screens/AboutUs.tsx index 50537cf..7ff65d3 100644 --- a/ui_tailwind_shadecn/src/screens/AboutUs.tsx +++ b/ui_tailwind_shadecn/src/screens/AboutUs.tsx @@ -1,4 +1,4 @@ -import MainNav from "@/components/custom_ui/MainNav" +import MainNav from "@/components/custom_ui/NavBar/MainNav" import ScroolCardReveal from "@/components/custom_ui/ScroolCardReveal" diff --git a/ui_tailwind_shadecn/src/screens/Auth/Login.tsx b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx index da7a343..aeeedd3 100644 --- a/ui_tailwind_shadecn/src/screens/Auth/Login.tsx +++ b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx @@ -1,7 +1,7 @@ import { MovingButton } from "@/components/ui/moving-border" import { Checkbox } from "@/components/ui/checkbox" -import MainNav from "@/components/custom_ui/MainNav" +import MainNav from "@/components/custom_ui/NavBar/MainNav" import { useLocation } from 'react-router-dom'; import { useEffect } from "react"; import {HandleLogin} from '@/hooks/handle_login.hooks'; diff --git a/ui_tailwind_shadecn/src/screens/Components.tsx b/ui_tailwind_shadecn/src/screens/Components.tsx index ab8fb40..e7e68a7 100644 --- a/ui_tailwind_shadecn/src/screens/Components.tsx +++ b/ui_tailwind_shadecn/src/screens/Components.tsx @@ -1,7 +1,6 @@ import { - Bell, - CircleUser, + Menu, Search, } from "lucide-react" @@ -14,14 +13,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card" -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" + import { Input } from "@/components/ui/input" import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet" import { Link } from "react-router-dom" @@ -29,7 +21,7 @@ import { Logo } from "@/components/custom_ui/Svg" import OutputsOfComponents from "@/components/custom_ui/OutputComponents" import { ComponentType } from "@/enums/iframEnums" import { useCategoriesStore, useComponentsStore } from "@/store/store" -import {useLoginStore} from "@/store/Auth" +// import {useLoginStore , useLoginUserInfo} from "@/store/Auth" import {ComponentsStore, } from '@/types/ComponentStore.type' import { useEffect } from "react" import { fetchCategories } from "@/api/components/categories" @@ -39,6 +31,8 @@ import { CardSkeleton } from "@/components/custom_ui/skeleton/CardSkeleton" import { useParams } from 'react-router-dom'; import {ComponentData} from '@/types/ComponentData.type'; import { Switch } from "@/components/ui/switch" +import { NavProfile } from "@/components/custom_ui/NavBar/NavProfile" +// import { json } from "stream/consumers" export function Components() { @@ -51,15 +45,17 @@ export function Components() { // this categries getting from a zustand store const categries = useCategoriesStore((state) => state.categories); const components = useComponentsStore((state) => state[catogries as keyof ComponentsStore] ?? 'all'); - const user = useLoginStore((state)=> state.user); - // useLoginStore.setState({isLogin: true}); + // const user = useLoginStore((state)=> state.isLogin); + // const userInfo = useLoginUserInfo((state)=> state) useEffect(() => { fetchCategories(); fetchComponentsStore(catogries ?? ''); }, [catogries]) + return ( +
@@ -162,31 +158,11 @@ export function Components() {
- - - - - - - My Account - - Settings - Support - - Logout - - +

{catogries} Components

-

{user ? user.name : "please login"}

diff --git a/ui_tailwind_shadecn/src/screens/Home.tsx b/ui_tailwind_shadecn/src/screens/Home.tsx index 3413041..d40ab47 100644 --- a/ui_tailwind_shadecn/src/screens/Home.tsx +++ b/ui_tailwind_shadecn/src/screens/Home.tsx @@ -21,7 +21,7 @@ import { MovingWords } from '@/data/MovingText'; import { Cateogries } from '@/data/ScroolingAnimations'; import { HeroParallax } from "@/components/ui/hero-parallax"; import { InfiniteMovingCards } from "@/components/ui/infinite-moving-cards"; -import MainNav from "@/components/custom_ui/MainNav"; +import MainNav from "@/components/custom_ui/NavBar/MainNav"; export function Dashboard() { diff --git a/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx b/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx new file mode 100644 index 0000000..e55e6de --- /dev/null +++ b/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx @@ -0,0 +1,213 @@ + +import { + Menu, + Search, + } from "lucide-react" + + import { Button } from "@/components/ui/button" + import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, + } from "@/components/ui/card" + + import { Input } from "@/components/ui/input" + import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet" + import { Link } from "react-router-dom" + import { Logo } from "@/components/custom_ui/Svg" + import { useCategoriesStore } from "@/store/store" + import { useEffect } from "react" + import { fetchCategories } from "@/api/components/categories" + import { fetchComponentsStore } from "@/api/components/components" + import { NavSkeleton } from "@/components/custom_ui/skeleton/NavSkeleton" + import { useParams } from 'react-router-dom'; +import { NavProfile } from "@/components/custom_ui/NavBar/NavProfile" + + export function Profile() { + + type componentsParamType = { + catogries?: string; + }; + + const { catogries } = useParams(); + + // this categries getting from a zustand store + const categries = useCategoriesStore((state) => state.categories); + // const user = useLoginStore((state)=> state.isLogin); + // const userInfo = useLoginUserInfo((state)=> state) + + useEffect(() => { + fetchCategories(); + fetchComponentsStore(catogries ?? ''); + }, [catogries]) + + + return ( + +
+
+
+
+ +
+

Ui Components

+
+ + {/* [mask-image:linear-gradient(to_top,transparent,white_50%,white_100%,transparent)] */} +
+ +
+ +
+
+
+
+
+ + + + + + + +
+ + + Join With Us + + Join the Revolution of Open Source UI + + + + + + +
+
+ +
+
+
+
+ + +
+
+
+ +
+
+ + +
+
+ + + +
+
+

Hi Olivia,

+

+ Alicia has invited you to join the team on{" "} + Meraki UI. +

+ +

+ Thanks,
+ Meraki UI team +

+
+ +
+ +
+
+
+ ) + } + \ No newline at end of file diff --git a/ui_tailwind_shadecn/src/screens/settings/layout.tsx b/ui_tailwind_shadecn/src/screens/settings/layout.tsx index 8c9d50f..5f3198c 100644 --- a/ui_tailwind_shadecn/src/screens/settings/layout.tsx +++ b/ui_tailwind_shadecn/src/screens/settings/layout.tsx @@ -1,7 +1,7 @@ import { Separator } from "@/components/ui/separator" import { SidebarNav } from "@/screens/settings/components/sidebar-nav" -import MainNav from "@/components/custom_ui/MainNav"; +import MainNav from "@/components/custom_ui/NavBar/MainNav"; export interface Metadata { diff --git a/ui_tailwind_shadecn/src/store/Auth.tsx b/ui_tailwind_shadecn/src/store/Auth.tsx index 5de47ff..ec0966c 100644 --- a/ui_tailwind_shadecn/src/store/Auth.tsx +++ b/ui_tailwind_shadecn/src/store/Auth.tsx @@ -1,22 +1,26 @@ -import { LoginStore } from '@/types/LoginStore.type'; +import { LoginStore, LoginUserInfoStore } from '@/types/LoginStore.type'; import { create } from 'zustand'; export const useLoginStore = create(() => ({ isLogin: false, - user: { - _id: "", - id: null, - login: null, - avatar_url: null, - url: null, - html_url: null, - company: null, - location: null, - email: null, - name: null, - blog: null, - bio: null, - twitter_username: null, - __v: 0 - } })); + + +export const useLoginUserInfo = create(() => ( + { + _id: "", + id: null, + login: null, + avatar_url: null, + url: null, + html_url: null, + company: null, + location: null, + email: null, + name: null, + blog: null, + bio: null, + twitter_username: null, + __v: 0 + } +)) \ No newline at end of file diff --git a/ui_tailwind_shadecn/src/types/LoginStore.type.tsx b/ui_tailwind_shadecn/src/types/LoginStore.type.tsx index 508cefd..4e19c21 100644 --- a/ui_tailwind_shadecn/src/types/LoginStore.type.tsx +++ b/ui_tailwind_shadecn/src/types/LoginStore.type.tsx @@ -1,6 +1,8 @@ export type LoginStore = { isLogin: boolean; - user: { +}; + +export type LoginUserInfoStore = { _id: string; id: number | null; login: string | null; @@ -15,5 +17,4 @@ export type LoginStore = { bio: string | null; twitter_username: string | null; __v: number; - } -}; +} \ No newline at end of file From 7944ab5edc28a19df279e7ce25b69c70dbb86daa Mon Sep 17 00:00:00 2001 From: agricreations Date: Tue, 23 Apr 2024 08:04:11 +0530 Subject: [PATCH 5/5] adding profile screens --- ui_tailwind_shadecn/package-lock.json | 18 +- ui_tailwind_shadecn/package.json | 4 +- .../src/components/ui/parallax-scrool.tsx | 84 ++++ .../src/screens/Auth/Login.tsx | 34 +- .../src/screens/Auth/MainAuth.tsx | 39 ++ .../src/screens/Profile/Profile.tsx | 415 ++++++++++-------- 6 files changed, 360 insertions(+), 234 deletions(-) create mode 100644 ui_tailwind_shadecn/src/components/ui/parallax-scrool.tsx create mode 100644 ui_tailwind_shadecn/src/screens/Auth/MainAuth.tsx diff --git a/ui_tailwind_shadecn/package-lock.json b/ui_tailwind_shadecn/package-lock.json index c0a2692..a9648dd 100644 --- a/ui_tailwind_shadecn/package-lock.json +++ b/ui_tailwind_shadecn/package-lock.json @@ -36,7 +36,7 @@ "clsx": "^2.1.0", "cmdk": "^1.0.0", "date-fns": "^3.6.0", - "framer-motion": "^11.1.5", + "framer-motion": "^11.1.7", "lucide-react": "^0.360.0", "monaco-editor": "^0.44.0", "next-themes": "^0.3.0", @@ -47,7 +47,7 @@ "react-resizable-panels": "^2.0.13", "react-router-dom": "^6.22.3", "sonner": "^1.4.41", - "tailwind-merge": "^2.2.2", + "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.0", "zod": "^3.22.4", @@ -4151,9 +4151,9 @@ } }, "node_modules/framer-motion": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.1.5.tgz", - "integrity": "sha512-ogK5fc0GBUT3AjzMXPx7f74m5V1ByRqkKQARBVHpdkYTNDxb/WriANYD+5JBo1wklQQJ1HayDZtmofQLqZFcbw==", + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.1.7.tgz", + "integrity": "sha512-cW11Pu53eDAXUEhv5hEiWuIXWhfkbV32PlgVISn7jRdcAiVrJ1S03YQQ0/DzoswGYYwKi4qYmHHjCzAH52eSdQ==", "dependencies": { "tslib": "^2.4.0" }, @@ -5761,11 +5761,11 @@ } }, "node_modules/tailwind-merge": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.2.tgz", - "integrity": "sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz", + "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==", "dependencies": { - "@babel/runtime": "^7.24.0" + "@babel/runtime": "^7.24.1" }, "funding": { "type": "github", diff --git a/ui_tailwind_shadecn/package.json b/ui_tailwind_shadecn/package.json index ab69ba1..d1f3fce 100644 --- a/ui_tailwind_shadecn/package.json +++ b/ui_tailwind_shadecn/package.json @@ -38,7 +38,7 @@ "clsx": "^2.1.0", "cmdk": "^1.0.0", "date-fns": "^3.6.0", - "framer-motion": "^11.1.5", + "framer-motion": "^11.1.7", "lucide-react": "^0.360.0", "monaco-editor": "^0.44.0", "next-themes": "^0.3.0", @@ -49,7 +49,7 @@ "react-resizable-panels": "^2.0.13", "react-router-dom": "^6.22.3", "sonner": "^1.4.41", - "tailwind-merge": "^2.2.2", + "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.0", "zod": "^3.22.4", diff --git a/ui_tailwind_shadecn/src/components/ui/parallax-scrool.tsx b/ui_tailwind_shadecn/src/components/ui/parallax-scrool.tsx new file mode 100644 index 0000000..5b850ae --- /dev/null +++ b/ui_tailwind_shadecn/src/components/ui/parallax-scrool.tsx @@ -0,0 +1,84 @@ +"use client"; +import { useScroll, useTransform } from "framer-motion"; +import { useRef } from "react"; +import { motion } from "framer-motion"; +import { cn } from "@/utils/cn"; + +export const ParallaxScroll = ({ + images, + className, +}: { + images: string[]; + className?: string; +}) => { + const gridRef = useRef(null); + const { scrollYProgress } = useScroll({ + container: gridRef, // remove this if your container is not fixed height + offset: ["start start", "end start"], // remove this if your container is not fixed height + }); + + const translateFirst = useTransform(scrollYProgress, [0, 1], [0, -200]); + const translateSecond = useTransform(scrollYProgress, [0, 1], [0, 200]); + const translateThird = useTransform(scrollYProgress, [0, 1], [0, -200]); + + const third = Math.ceil(images.length / 3); + + const firstPart = images.slice(0, third); + const secondPart = images.slice(third, 2 * third); + const thirdPart = images.slice(2 * third); + + return ( +
+
+
+ {firstPart.map((el, idx) => ( + + thumbnail + + ))} +
+
+ {secondPart.map((el, idx) => ( + + thumbnail + + ))} +
+
+ {thirdPart.map((el, idx) => ( + + thumbnail + + ))} +
+
+
+ ); +}; diff --git a/ui_tailwind_shadecn/src/screens/Auth/Login.tsx b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx index aeeedd3..bf57233 100644 --- a/ui_tailwind_shadecn/src/screens/Auth/Login.tsx +++ b/ui_tailwind_shadecn/src/screens/Auth/Login.tsx @@ -1,10 +1,8 @@ -import { MovingButton } from "@/components/ui/moving-border" -import { Checkbox } from "@/components/ui/checkbox" import MainNav from "@/components/custom_ui/NavBar/MainNav" import { useLocation } from 'react-router-dom'; import { useEffect } from "react"; -import {HandleLogin} from '@/hooks/handle_login.hooks'; +import { MainAuth } from "./MainAuth"; export function Login() { @@ -22,35 +20,7 @@ export function Login() { <> < MainNav/>
-
-
-
-

Login or Signup

-

- Create Your Account with github -

-
-
- - -
-
- - Signup With Github - -
-
-
+
{ + return( + <> +
+
+
+

Login or Signup

+

+ Create Your Account with github +

+
+
+ + +
+
+ + Signup With Github + +
+
+
+ + ) +} \ No newline at end of file diff --git a/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx b/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx index e55e6de..fa400a8 100644 --- a/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx +++ b/ui_tailwind_shadecn/src/screens/Profile/Profile.tsx @@ -2,212 +2,245 @@ import { Menu, Search, - } from "lucide-react" - - import { Button } from "@/components/ui/button" - import { +} from "lucide-react" + +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardDescription, CardHeader, CardTitle, - } from "@/components/ui/card" - - import { Input } from "@/components/ui/input" - import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet" - import { Link } from "react-router-dom" - import { Logo } from "@/components/custom_ui/Svg" - import { useCategoriesStore } from "@/store/store" - import { useEffect } from "react" - import { fetchCategories } from "@/api/components/categories" - import { fetchComponentsStore } from "@/api/components/components" - import { NavSkeleton } from "@/components/custom_ui/skeleton/NavSkeleton" - import { useParams } from 'react-router-dom'; +} from "@/components/ui/card" + +import { Input } from "@/components/ui/input" +import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet" +import { Link, Navigate } from "react-router-dom" +import { Logo } from "@/components/custom_ui/Svg" +import { useCategoriesStore } from "@/store/store" +import { useEffect } from "react" +import { fetchCategories } from "@/api/components/categories" +import { fetchComponentsStore } from "@/api/components/components" +import { NavSkeleton } from "@/components/custom_ui/skeleton/NavSkeleton" +import { useParams } from 'react-router-dom'; import { NavProfile } from "@/components/custom_ui/NavBar/NavProfile" - - export function Profile() { - +import { ParallaxScroll } from "@/components/ui/parallax-scrool"; +import { useLoginStore, useLoginUserInfo } from "@/store/Auth" +import { MainAuth } from "@/screens/Auth/MainAuth"; + + +const images = [ + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1682686581854-5e71f58e7e3f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1510784722466-f2aa9c52fff6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1505765050516-f72dcac9c60e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1439853949127-fa647821eba0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2640&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", + "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3540&q=80", + "https://images.unsplash.com/photo-1554080353-a576cf803bda?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3387&q=80", + "https://images.unsplash.com/photo-1505144808419-1957a94ca61e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3070&q=80", +]; + +export function Profile() { + + // const user = useLoginStore((state) => state.isLogin); + const user = true; + const userInfo = useLoginUserInfo((state) => state); + type componentsParamType = { - catogries?: string; + catogries?: string; }; - + const { catogries } = useParams(); - - // this categries getting from a zustand store const categries = useCategoriesStore((state) => state.categories); - // const user = useLoginStore((state)=> state.isLogin); - // const userInfo = useLoginUserInfo((state)=> state) - + useEffect(() => { - fetchCategories(); - fetchComponentsStore(catogries ?? ''); + fetchCategories(); + fetchComponentsStore(catogries ?? ''); }, [catogries]) - - + + + return ( - -
-
-
-
- -
-

Ui Components

+ +
+
+
+
+ +
+

Ui Components

+
+ + {/* [mask-image:linear-gradient(to_top,transparent,white_50%,white_100%,transparent)] */} +
+ +
+ +
+
- - {/* [mask-image:linear-gradient(to_top,transparent,white_50%,white_100%,transparent)] */} -
- + + +
+ + + + +
+
+
+
+ +
+
+

+ Moovendhan +

+

+ company +

+
+ "After all," he said, "everyone enjoys a good joke, so it's only fair that + they should pay for the privilege." +
+
+
+ + @agricreations + + +
+
+ + @agricreations + + +
+
+
+
+
+
+ + + + {/* */} + + +
- -
-
-
-
-
- - - - - - - -
- - - Join With Us - - Join the Revolution of Open Source UI - - - - - - -
-
- -
-
-
-
- - -
-
-
- -
-
- - -
-
- - - -
-
-

Hi Olivia,

-

- Alicia has invited you to join the team on{" "} - Meraki UI. -

- -

- Thanks,
- Meraki UI team -

-
- -
- -
+: <> + +} + +
-
+ ) - } - \ No newline at end of file +} + +