From 387c195856ab723a262263b365b6391a832fcb59 Mon Sep 17 00:00:00 2001 From: Aamil13 Date: Wed, 22 May 2024 14:50:04 +0530 Subject: [PATCH 1/2] es-fix --- package-lock.json | 38 +++++++++++++++++++++++++++++++- package.json | 3 ++- src/app/page.tsx | 3 +++ src/hooks/useCookie.ts | 23 +++++++++++++++++++ src/models/auth.ts | 11 +++++++++ src/services/auth.ts | 18 +++++++++++++-- src/store/store.ts | 19 ++++++++++++++++ src/store/storeType.ts | 3 +++ src/store/userSlice/userSlice.ts | 35 +++++++++++++++++++++++++++++ src/store/userSlice/userType.ts | 22 ++++++++++++++++++ tsconfig.json | 2 +- 11 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/hooks/useCookie.ts create mode 100644 src/store/store.ts create mode 100644 src/store/storeType.ts create mode 100644 src/store/userSlice/userSlice.ts create mode 100644 src/store/userSlice/userType.ts diff --git a/package-lock.json b/package-lock.json index 2a4bf6b..21f31c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,8 @@ "storybook-addon-apollo-client": "^5.0.0", "swiper": "^11.0.7", "tailwindcss": "3.3.3", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "zustand": "^4.5.2" }, "devDependencies": { "@jest/globals": "^29.7.0", @@ -22046,6 +22047,14 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -23014,6 +23023,33 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zustand": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz", + "integrity": "sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index f466839..a7af82a 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,8 @@ "storybook-addon-apollo-client": "^5.0.0", "swiper": "^11.0.7", "tailwindcss": "3.3.3", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "zustand": "^4.5.2" }, "devDependencies": { "@jest/globals": "^29.7.0", diff --git a/src/app/page.tsx b/src/app/page.tsx index c13751c..add6479 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -12,10 +12,13 @@ import { motion } from 'framer-motion' import StarIcon from '../assets/stars.svg' import Image from 'next/image' import DiscordIcon from '@assets/discord.svg' +import useCookie from '@/hooks/useCookie' export default function Home() { const [searchOpen, setSearchOpen] = useState(false) const LANDING_PAGE_TEXT = ' Search universities worldwide and become part of their online communities'.split(' ') + const [cookieValue] = useCookie('uni_user_token') + console.log(cookieValue) return (
diff --git a/src/hooks/useCookie.ts b/src/hooks/useCookie.ts new file mode 100644 index 0000000..0a064f8 --- /dev/null +++ b/src/hooks/useCookie.ts @@ -0,0 +1,23 @@ +import { useState, useEffect } from 'react' + +const useCookie = (cookieName: string): [string, (value: string, expirationDate: string) => void, () => void] => { + const [cookieValue, setCookieValue] = useState('') + + useEffect(() => { + const cookie = document.cookie.split('; ').find((row) => row.startsWith(`${cookieName}=`)) + + setCookieValue(cookie ? cookie.split('=')[1] : '') + }, [cookieName]) + + const setCookie = (value: string, expirationDate: string): void => { + document.cookie = `${cookieName}=${value}; expires=${new Date(expirationDate).toUTCString()}; path=/` + } + + const deleteCookie = (): void => { + document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/` + } + + return [cookieValue, setCookie, deleteCookie] +} + +export default useCookie diff --git a/src/models/auth.ts b/src/models/auth.ts index cc62b4d..42914c8 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -8,6 +8,15 @@ export interface UserResponseType { tokens: Tokens } +interface verifiedInterface { + communityId: string + communityName: string +} +interface unverifiedInterface { + communityId: string + communityName: string +} + export interface User { firstName: string lastName: string @@ -17,6 +26,8 @@ export interface User { role: string isEmailVerified: boolean id: string + userVerifiedCommunities: verifiedInterface[] + userUnVerifiedCommunities: unverifiedInterface[] } export interface Tokens { diff --git a/src/services/auth.ts b/src/services/auth.ts index dc55bdb..6af23c3 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -1,16 +1,30 @@ import { LoginForm, UserResponseType } from '@/models/auth' import { useMutation } from '@tanstack/react-query' import { client } from './api-Client' +import { useUniStore } from '@/store/store' +import useCookie from '@/hooks/useCookie' const login = async (data: LoginForm): Promise => { const result = await client('auth/login', { data }) return result } -export const useHandleLogin = () => - useMutation({ +export const useHandleLogin = () => { + const setUserData = useUniStore((state) => state.setUserData) + // const setToken = useUniStore((state) => state.setToken) + const [_, setCookieValue] = useCookie('uni_user_token') + const [__, setRefreshCookieValue] = useCookie('uni_user_refresh_token') + + return useMutation({ mutationFn: (data: LoginForm) => login(data), onSuccess: (response) => { console.log(response, 'response') + console.log(_, __) + + setUserData(response.user) + // setToken(response.tokens) + setCookieValue(response.tokens.access.token, response.tokens.access.expires) + setRefreshCookieValue(response.tokens.refresh.token, response.tokens.refresh.expires) }, }) +} diff --git a/src/store/store.ts b/src/store/store.ts new file mode 100644 index 0000000..f33fb14 --- /dev/null +++ b/src/store/store.ts @@ -0,0 +1,19 @@ +import { create } from 'zustand' +import { devtools, persist } from 'zustand/middleware' +import { createUserSlice } from './userSlice/userSlice' +import { storeType } from './storeType' + +export const useUniStore = create()( + devtools( + persist( + (...a) => ({ + ...createUserSlice(...a), + }), + { + name: 'UniStore', + // partialize: (state) => ({ products: state.products,userName:state.userName }), + // skipHydration: true + } + ) + ) +) diff --git a/src/store/storeType.ts b/src/store/storeType.ts new file mode 100644 index 0000000..e60e63d --- /dev/null +++ b/src/store/storeType.ts @@ -0,0 +1,3 @@ +import { userSlice } from './userSlice/userSlice' + +export type storeType = userSlice diff --git a/src/store/userSlice/userSlice.ts b/src/store/userSlice/userSlice.ts new file mode 100644 index 0000000..7948601 --- /dev/null +++ b/src/store/userSlice/userSlice.ts @@ -0,0 +1,35 @@ +import { StateCreator } from 'zustand' +import { userType } from './userType' + +type userState = { + userData: userType +} + +type userAction = { + setUserData: (userData: userType) => void + resetUserData: () => void +} + +const initialState: userState = { + userData: { + firstName: '', + lastName: '', + email: '', + // password: '', + gender: '', + dob: '', + role: '', + isEmailVerified: false, + // createdAt: '', + userVerifiedCommunities: [], + userUnVerifiedCommunities: [], + }, +} + +export type userSlice = userState & userAction + +export const createUserSlice: StateCreator = (set) => ({ + userData: initialState.userData, + setUserData: (userData: userType) => set({ userData }), + resetUserData: () => set(initialState), +}) diff --git a/src/store/userSlice/userType.ts b/src/store/userSlice/userType.ts new file mode 100644 index 0000000..ffeb1bb --- /dev/null +++ b/src/store/userSlice/userType.ts @@ -0,0 +1,22 @@ +interface verifiedInterface { + communityId: string + communityName: string +} +interface unverifiedInterface { + communityId: string + communityName: string +} + +export interface userType { + firstName: string + lastName: string + email: string + // password: string + gender: string + dob: string + role: string + isEmailVerified: boolean + // createdAt: Date | string + userVerifiedCommunities: verifiedInterface[] + userUnVerifiedCommunities: unverifiedInterface[] +} diff --git a/tsconfig.json b/tsconfig.json index 6520a6c..ad848dc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,7 +38,7 @@ "jest.config.ts", "jest.setup.js", "src/app/components/Slider/Slider.js" - ], +, "src/store/userSlice" ], "exclude": [ "node_modules" ] From 801d34131893e4840825525915d6fb411bb78fd6 Mon Sep 17 00:00:00 2001 From: Aamil13 Date: Wed, 29 May 2024 11:39:05 +0530 Subject: [PATCH 2/2] removed test cases --- src/__tests__/home.test.tsx | 16 -------- src/__tests__/query.test.tsx | 65 -------------------------------- src/__tests__/searchBar.test.tsx | 35 ----------------- 3 files changed, 116 deletions(-) delete mode 100644 src/__tests__/home.test.tsx delete mode 100644 src/__tests__/query.test.tsx delete mode 100644 src/__tests__/searchBar.test.tsx diff --git a/src/__tests__/home.test.tsx b/src/__tests__/home.test.tsx deleted file mode 100644 index 10f0c03..0000000 --- a/src/__tests__/home.test.tsx +++ /dev/null @@ -1,16 +0,0 @@ -// import '@testing-library/jest-dom' - -// import SearchBar from '@/components/SearchBar' -// import { render } from '@testing-library/react' - -// it('renders a search box', () => { -// const mockData = [ -// { id: '1', name: 'College 1', score: '85', address: '...', collegePage: '...' }, -// { id: '2', name: 'College 2', score: '70', address: '...', collegePage: '...' }, -// ] -// const { getByPlaceholderText } = render() - -// const subject = getByPlaceholderText('Search institute') - -// expect(subject).toBeInTheDocument() -// }) diff --git a/src/__tests__/query.test.tsx b/src/__tests__/query.test.tsx deleted file mode 100644 index c9c8b1b..0000000 --- a/src/__tests__/query.test.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import '@testing-library/jest-dom' - -import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client' - -import fetch from 'cross-fetch' -import { gql } from '@apollo/client' - -interface College { - id: string - name: string - score: string - city: string - country: string -} - -const query = gql` - query getUniversityList { - universityList { - id - name - score - country - city - } - } -` - -const uri = 'https://web-app-client-b69l4yjrq-bacpacs-projects.vercel.app/api/graphql' -console.log('GraphQL URI in tests:', uri) -const client = new ApolloClient({ - link: new HttpLink({ uri, fetch }), - cache: new InMemoryCache(), -}) -// test to check the data is not empty -test('the data is of college', async () => { - const result = await client.query({ query }) - - expect(result?.data).not.toBeNull() - expect(result?.data).toHaveProperty('universityList') - expect(result?.data?.universityList).toBeInstanceOf(Array) - expect(result?.data?.universityList?.length).toBeGreaterThan(0) -}) -// test to check the format of data recived by the query -test('the data has specific properties', async () => { - const result = await client.query({ query }) - - result?.data?.universityList?.forEach((college: College) => { - // check for id property - expect(college).toHaveProperty('id') - expect(college?.id).not.toBeNull() - expect(typeof college?.id).toBe('string') - // check for name property - expect(college).toHaveProperty('name') - expect(college?.name).not.toBeNull() - expect(typeof college?.name).toBe('string') - // check for score property - expect(college).toHaveProperty('score') - expect(college?.score).not.toBeNull() - expect(typeof college?.score).toBe('string') - // check for country property - expect(college).toHaveProperty('country') - expect(college?.country).not.toBeNull() - expect(typeof college?.country).toBe('string') - }) -}) diff --git a/src/__tests__/searchBar.test.tsx b/src/__tests__/searchBar.test.tsx deleted file mode 100644 index f6eca55..0000000 --- a/src/__tests__/searchBar.test.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import '@testing-library/jest-dom' - -import { fireEvent, render } from '@testing-library/react' - -import SearchBar from '@/components/SearchBar' -import data from '../../data/university_data.json' - -it('display filtered data based on input', () => { - const { getByPlaceholderText, queryByText } = render() - const input = getByPlaceholderText('Search institute') - - fireEvent.change(input, { target: { value: 'Bhubaneswar' } }) - - expect(queryByText('Indian Institute of Technology Bhubaneswar')).toBeInTheDocument() - expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull() -}) - -it('handles case-insensitive filtering', () => { - const { getByPlaceholderText, queryByText } = render() - const input = getByPlaceholderText('Search institute') - - fireEvent.change(input, { target: { value: 'bhub' } }) - - expect(queryByText('Indian Institute of Technology Bhubaneswar')).toBeInTheDocument() - expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull() -}) - -it('should display "No results found" if no matching results are found', () => { - const { getByPlaceholderText, queryByText } = render() - const input = getByPlaceholderText('Search institute') - - fireEvent.change(input, { target: { value: 'qwertyuiop' } }) - - expect(queryByText('No results found')).toBeInTheDocument() -})