diff --git a/frontend/src/components/AppContent.tsx b/frontend/src/components/AppContent.tsx index e8d085b..5eefdb1 100644 --- a/frontend/src/components/AppContent.tsx +++ b/frontend/src/components/AppContent.tsx @@ -1,5 +1,5 @@ import {FirebaseProvider} from '@/hooks/FirebaseContext'; -import {useCheckTokenStatus} from '@/hooks/useGetTokenStatus'; +import {useCheckTokenStatus} from '@/src/hooks/useGetTokenStatus'; import {useNotificationListeners} from '@/hooks/useNotificationListener'; import {useVersionCheck} from '@/hooks/useVersionCheck'; import {SocketProvider} from '@/SocketContext'; @@ -23,6 +23,7 @@ import {setConnected} from '../store/NetworkSlice'; import {firebaseInit} from '../helper/firebase'; import {cleanUpDownloads, KEYS, retrieveItem} from '../helper/Utils'; import { setUserToken } from '../store/UserSlice'; +import axios from 'axios'; export default function AppContent() { const navigationRef = useRef(null); @@ -32,6 +33,7 @@ export default function AppContent() { }; const {data: tokenRes = null, isLoading} = useCheckTokenStatus(); + const {visible, storeUrl} = useVersionCheck(); const dispatch = useDispatch(); @@ -43,8 +45,10 @@ export default function AppContent() { }, [tokenRes, isLoading]); const checkToken = async () =>{ - const token = await retrieveItem(KEYS.USER_TOKEN); - + const token = await retrieveItem(KEYS.USER_TOKEN); + //axios.defaults.headers. + axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; + axios.defaults.headers.common["Content-Type"] = "application/json"; dispatch(setUserToken(token)); initDeepLinking(navigationRef.current, tokenRes?.isValid || false); diff --git a/frontend/src/hooks/useArticleRepost.ts b/frontend/src/hooks/useArticleRepost.ts new file mode 100644 index 0000000..45295b4 --- /dev/null +++ b/frontend/src/hooks/useArticleRepost.ts @@ -0,0 +1,18 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import {REPOST_ARTICLE} from '../helper/APIUtils'; +import axios, {AxiosError} from 'axios'; + +export const useRepostArticle = ( + +): UseMutationResult => { + return useMutation({ + mutationKey: [`repost-article`], + mutationFn: async ( articleId: number,) => { + const res = await axios.post(REPOST_ARTICLE, { + articleId: articleId, + }); + + return res.data as any; + }, + }); +}; diff --git a/frontend/src/hooks/useChangePassword.ts b/frontend/src/hooks/useChangePassword.ts new file mode 100644 index 0000000..1e76ed3 --- /dev/null +++ b/frontend/src/hooks/useChangePassword.ts @@ -0,0 +1,24 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {CHANGE_PASSWORD_API} from '../helper/APIUtils'; + +type ChangePassWordReq = { + email: string; + newPassword: string; +}; +export const useChangePasswordMutation = (): UseMutationResult< + any, + AxiosError, + ChangePassWordReq +> => { + return useMutation({ + mutationKey: ['generate-new-password'], + mutationFn: async (req: ChangePassWordReq) => { + const res = await axios.post(CHANGE_PASSWORD_API, { + email: req.email, + newPassword: req.newPassword, + }); + return res.data as any; + }, + }); +}; diff --git a/frontend/src/hooks/useCheckUserHandle.ts b/frontend/src/hooks/useCheckUserHandle.ts new file mode 100644 index 0000000..5c7fc98 --- /dev/null +++ b/frontend/src/hooks/useCheckUserHandle.ts @@ -0,0 +1,18 @@ +import { useQuery } from "@tanstack/react-query"; +import axios from "axios"; +import { CHECK_USER_HANDLE } from "../helper/APIUtils"; + +export const useCheckUserHandleAvailability = (handle: string) => { + return useQuery({ + queryKey: ["check-user-handle", handle], + queryFn: async () => { + const response = await axios.post(CHECK_USER_HANDLE, { + userHandle: handle, + }); + + return response.data; + }, + enabled: handle.length > 2, + retry: false, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetArticleContent.ts b/frontend/src/hooks/useGetArticleContent.ts new file mode 100644 index 0000000..0b089b2 --- /dev/null +++ b/frontend/src/hooks/useGetArticleContent.ts @@ -0,0 +1,15 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {GET_ARTICLE_CONTENT} from '../helper/APIUtils'; + +export const useGetArticleContent = ( + recordId: string, +): UseQueryResult => { + return useQuery({ + queryKey: ['get-article-content', recordId], + queryFn: async () => { + const response = await axios.get(`${GET_ARTICLE_CONTENT}/${recordId}`); + return response.data.htmlContent as string; + }, + }); +}; diff --git a/frontend/src/hooks/useGetArticleDetail.ts b/frontend/src/hooks/useGetArticleDetail.ts new file mode 100644 index 0000000..9e91efe --- /dev/null +++ b/frontend/src/hooks/useGetArticleDetail.ts @@ -0,0 +1,17 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import {ArticleData} from '../type'; +import axios, {AxiosError} from 'axios'; +import {GET_ARTICLE_BY_ID} from '../helper/APIUtils'; + +export const useGetArticleDetails = ( + articleId: number, +): UseQueryResult => { + return useQuery({ + queryKey: ['get-article-by-id', articleId], + queryFn: async () => { + const response = await axios.get(`${GET_ARTICLE_BY_ID}/${articleId}`); + + return response.data.article as ArticleData; + }, + }); +}; diff --git a/frontend/src/hooks/useGetArticleTags.ts b/frontend/src/hooks/useGetArticleTags.ts new file mode 100644 index 0000000..94955d3 --- /dev/null +++ b/frontend/src/hooks/useGetArticleTags.ts @@ -0,0 +1,28 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {ARTICLE_TAGS_API, PROD_URL} from '../helper/APIUtils'; +import {Category} from '../type'; + +const categoryFunc = async () => { + try{ + const {data: categoryData} = await axios.get( + `${PROD_URL + ARTICLE_TAGS_API}`, + ); + + return categoryData as Category[]; + }catch(err){ + console.log("GET CATEGORY ERR", err); + return null; + } +}; + +export const useGetCategories = (isConnected: boolean): UseQueryResult< + Category[] | null, + AxiosError +> => { + return useQuery({ + queryKey: ['get-categories'], + queryFn: categoryFunc, + enabled: isConnected + }); +}; diff --git a/frontend/src/hooks/useGetImprovementById.ts b/frontend/src/hooks/useGetImprovementById.ts new file mode 100644 index 0000000..e8fb2aa --- /dev/null +++ b/frontend/src/hooks/useGetImprovementById.ts @@ -0,0 +1,17 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import {EditRequest} from '../type'; +import axios, {AxiosError} from 'axios'; +import {GET_IMPROVEMENT_BY_ID} from '../helper/APIUtils'; + +export const useGetImprovementById = ( + requestId: string, +): UseQueryResult => { + return useQuery({ + queryKey: ['get-improvement-by-id', requestId], + queryFn: async () => { + const response = await axios.get(`${GET_IMPROVEMENT_BY_ID}/${requestId}`); + + return response.data as EditRequest; + }, + }); +}; diff --git a/frontend/src/hooks/useGetImprovementContent.ts b/frontend/src/hooks/useGetImprovementContent.ts new file mode 100644 index 0000000..f52e915 --- /dev/null +++ b/frontend/src/hooks/useGetImprovementContent.ts @@ -0,0 +1,31 @@ +import { useQuery } from '@tanstack/react-query'; +import axios from 'axios'; +import { GET_IMPROVEMENT_CONTENT } from '../helper/APIUtils'; + +interface Props { + recordId?: string; + articleRecordId?: string; +} + +export const useGetImprovementContent = ({ + recordId, + articleRecordId, +}: Props) => { + return useQuery({ + queryKey: ['get-improvement-content', recordId, articleRecordId], + queryFn: async () => { + let url = ''; + + if (recordId) { + url = `${GET_IMPROVEMENT_CONTENT}?articleRecordId=${articleRecordId}`; + } else { + url = `${GET_IMPROVEMENT_CONTENT}?recordid=${recordId}&articleRecordId=${articleRecordId}`; + } + + const response = await axios.get(url); + + return response.data.htmlContent as string; + }, + enabled: !!articleRecordId, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetMonthlyReadReport.ts b/frontend/src/hooks/useGetMonthlyReadReport.ts new file mode 100644 index 0000000..9d6cc3e --- /dev/null +++ b/frontend/src/hooks/useGetMonthlyReadReport.ts @@ -0,0 +1,36 @@ + +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { MonthStatus } from "../type"; +import { GET_MONTHLY_READ_REPORT } from "../helper/APIUtils"; + +export const useGetAuthorMonthlyReadReport = ( + user_id: string, + selectedMonth: number, + userId?: string, + others?: boolean, + isConnected?: boolean, + +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-user-monthly-read-report", user_id, userId, others], + + queryFn: async () => { + + if(selectedMonth === -1){ + return []; + } + + let url = others + ? `${GET_MONTHLY_READ_REPORT}?userId=${userId}&month=${selectedMonth}` + : `${GET_MONTHLY_READ_REPORT}?userId=${user_id}&month=${selectedMonth}`; + + const response = await axios.get(url); + + return response.data.monthlyReads as MonthStatus[]; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetMonthlyWriteReport.ts b/frontend/src/hooks/useGetMonthlyWriteReport.ts new file mode 100644 index 0000000..a2c3702 --- /dev/null +++ b/frontend/src/hooks/useGetMonthlyWriteReport.ts @@ -0,0 +1,35 @@ + +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { MonthStatus } from "../type"; +import { GET_MONTHLY_WRITES_REPORT } from "../helper/APIUtils"; + +export const useGetAuthorMonthlyReadReport = ( + user_id: string, + selectedMonth: number, + userId?: string, + others?: boolean, + isConnected?: boolean, +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-user-monthly-write-report", user_id, userId, others], + + queryFn: async () => { + + if(selectedMonth === -1){ + return []; + } + + let url = others + ? `${GET_MONTHLY_WRITES_REPORT}?userId=${userId}&month=${selectedMonth}` + : `${GET_MONTHLY_WRITES_REPORT}?userId=${user_id}&month=${selectedMonth}`; + + const response = await axios.get(url); + + return response.data.monthlyWrites as MonthStatus[]; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetMostViewedArticle.ts b/frontend/src/hooks/useGetMostViewedArticle.ts new file mode 100644 index 0000000..4d69035 --- /dev/null +++ b/frontend/src/hooks/useGetMostViewedArticle.ts @@ -0,0 +1,30 @@ + +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { ArticleData } from "../type"; +import { GET_MOSTLY_VIEWED } from "../helper/APIUtils"; + +export const useGetAuthorMostViewedArticles = ( + user_id: string, + userId?: string, + others?: boolean, + isConnected?: boolean +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-mostly-viewed-article", user_id, userId, others], + + queryFn: async () => { + + const url = others + ? `${GET_MOSTLY_VIEWED}${userId}` + : `${GET_MOSTLY_VIEWED}${user_id}`; + + const response = await axios.get(url); + + return response.data as ArticleData[]; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetProfile.ts b/frontend/src/hooks/useGetProfile.ts new file mode 100644 index 0000000..fdd6760 --- /dev/null +++ b/frontend/src/hooks/useGetProfile.ts @@ -0,0 +1,14 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import {User} from '../type'; +import axios, {AxiosError} from 'axios'; +import {GET_PROFILE_API} from '../helper/APIUtils'; + +export const useGetProfile = (): UseQueryResult => { + return useQuery({ + queryKey: ['get-my-profile'], + queryFn: async () => { + const response = await axios.get(`${GET_PROFILE_API}`); + return response.data.profile as User; + }, + }); +}; diff --git a/frontend/src/hooks/useGetProfileImageById.ts b/frontend/src/hooks/useGetProfileImageById.ts new file mode 100644 index 0000000..abeedae --- /dev/null +++ b/frontend/src/hooks/useGetProfileImageById.ts @@ -0,0 +1,18 @@ +import axios, { AxiosError } from "axios"; +import { GET_PROFILE_IMAGE_BY_ID } from "../helper/APIUtils"; +import { useQuery, UseQueryResult } from "@tanstack/react-query"; + +export const useGetUserProfileImage = (authorId: string): UseQueryResult< + string, + AxiosError +>=>{ + + return useQuery({ + queryKey: ['author_profile_image', authorId], + queryFn: async () => { + const response = await axios.get( + `${GET_PROFILE_IMAGE_BY_ID}/${authorId}`); + return response.data.profile_image as string; + }, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useGetReportReasons.ts b/frontend/src/hooks/useGetReportReasons.ts new file mode 100644 index 0000000..8d6383a --- /dev/null +++ b/frontend/src/hooks/useGetReportReasons.ts @@ -0,0 +1,28 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {GET_REPORT_REASONS} from '../helper/APIUtils'; +import {ReportReason} from '../type'; + +const reasonsFunc = async () => { + try{ + const {data: categoryData} = await axios.get( + GET_REPORT_REASONS + ); + + return categoryData as ReportReason[]; + }catch(err){ + console.log("GET CATEGORY ERR", err); + return null; + } +}; + +export const useGetReasons = (isConnected: boolean): UseQueryResult< + ReportReason[] | null, + AxiosError +> => { + return useQuery({ + queryKey: ['get-report-reasons'], + queryFn: reasonsFunc, + enabled: isConnected + }); +}; diff --git a/frontend/hooks/useGetTokenStatus.ts b/frontend/src/hooks/useGetTokenStatus.ts similarity index 100% rename from frontend/hooks/useGetTokenStatus.ts rename to frontend/src/hooks/useGetTokenStatus.ts diff --git a/frontend/src/hooks/useGetTotalLikeViewStatus.ts b/frontend/src/hooks/useGetTotalLikeViewStatus.ts new file mode 100644 index 0000000..811aa45 --- /dev/null +++ b/frontend/src/hooks/useGetTotalLikeViewStatus.ts @@ -0,0 +1,30 @@ +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { UserStatus } from "../type"; +import { GET_TOTAL_LIKES_VIEWS } from "../helper/APIUtils"; + +export const useGetTotalLikeViewStatus = ( + user_id: string, + userId?: string, + others?: boolean, + isConnected?: boolean +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-like-view-status", user_id, userId, others], + + queryFn: async () => { + + + const url = others + ? `${GET_TOTAL_LIKES_VIEWS}${userId}` + : `${GET_TOTAL_LIKES_VIEWS}${user_id}`; + + const response = await axios.get(url); + + return response.data as UserStatus; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetTotalReads.ts b/frontend/src/hooks/useGetTotalReads.ts new file mode 100644 index 0000000..7a1d226 --- /dev/null +++ b/frontend/src/hooks/useGetTotalReads.ts @@ -0,0 +1,30 @@ + +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { ReadStatus } from "../type"; +import { GET_TOTAL_READS } from "../helper/APIUtils"; + +export const useGetTotalReads = ( + user_id: string, + userId?: string, + others?: boolean, + isConnected?: boolean +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-total-reads", user_id, userId, others], + + queryFn: async () => { + + const url = others + ? `${GET_TOTAL_READS}${userId}` + : `${GET_TOTAL_READS}${user_id}`; + + const response = await axios.get(url); + + return response.data as ReadStatus; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetTotalWrites.ts b/frontend/src/hooks/useGetTotalWrites.ts new file mode 100644 index 0000000..67d5eeb --- /dev/null +++ b/frontend/src/hooks/useGetTotalWrites.ts @@ -0,0 +1,30 @@ + +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios from "axios"; +import { WriteStatus } from "../type"; +import { GET_TOTAL_WRITES } from "../helper/APIUtils"; + +export const useGetTotalReads = ( + user_id: string, + userId?: string, + others?: boolean, + isConnected?: boolean +): UseQueryResult => { + + return useQuery({ + queryKey: ["get-total-writes", user_id, userId, others], + + queryFn: async () => { + + const url = others + ? `${GET_TOTAL_WRITES}${userId}` + : `${GET_TOTAL_WRITES}${user_id}`; + + const response = await axios.get(url); + + return response.data as WriteStatus; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetUserAllArticles.ts b/frontend/src/hooks/useGetUserAllArticles.ts new file mode 100644 index 0000000..0e5adde --- /dev/null +++ b/frontend/src/hooks/useGetUserAllArticles.ts @@ -0,0 +1,65 @@ +import { useQuery } from '@tanstack/react-query'; +import axios from 'axios'; +import { ArticleData } from '../type'; +import { GET_ALL_ARTICLES_FOR_USER } from '../helper/APIUtils'; + +interface Props { + page: number; + selectedStatus: string; + visit: number; + setVisit: (v: number) => void; + setTotalPages: (v: number) => void; + setArticleData: React.Dispatch>; + setPublishedLabel: (v: string) => void; + setProgressLabel: (v: string) => void; + setDiscardLabel: (v: string) => void; +} + +export const useGetAllArticlesForUser = ({ + page, + selectedStatus, + visit, + setVisit, + setTotalPages, + setArticleData, + setPublishedLabel, + setProgressLabel, + setDiscardLabel, +}: Props) => { + return useQuery({ + queryKey: ['get-all-articles-for-user', page, selectedStatus], + queryFn: async () => { + const response = await axios.get( + `${GET_ALL_ARTICLES_FOR_USER}?page=${page}&status=${selectedStatus}` + ); + + const data = response.data; + + if (Number(page) === 1 && data.totalPages) { + setTotalPages(data.totalPages); + setArticleData(data.articles); + } else if (Array.isArray(data.articles)) { + setArticleData(prev => [...prev, ...data.articles]); + } + + if (Number(visit) === 1) { + if (data.publishedCount) { + setPublishedLabel(`Published(${data.publishedCount})`); + } + + if (data.progressCount) { + setProgressLabel(`Progress(${data.progressCount})`); + } + + if (data.discardCount) { + setDiscardLabel(`Discarded(${data.discardCount})`); + } + + setVisit(0); + } + + return data.articles as ArticleData[]; + }, + enabled: !!page, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetUserAllImprovements.ts b/frontend/src/hooks/useGetUserAllImprovements.ts new file mode 100644 index 0000000..b479673 --- /dev/null +++ b/frontend/src/hooks/useGetUserAllImprovements.ts @@ -0,0 +1,65 @@ +import { useQuery } from '@tanstack/react-query'; +import axios from 'axios'; +import { EditRequest } from '../type'; +import { GET_ALL_IMPROVEMENTS_FOR_USER } from '../helper/APIUtils'; + +interface Props { + page: number; + selectedStatus: string; + visit: number; + setVisit: (v: number) => void; + setTotalPages: (v: number) => void; + setImprovementData: React.Dispatch>; + setPublishedLabel: (v: string) => void; + setProgressLabel: (v: string) => void; + setDiscardLabel: (v: string) => void; +} + +export const useGetAllImprovementsForReview = ({ + page, + selectedStatus, + visit, + setVisit, + setTotalPages, + setImprovementData, + setPublishedLabel, + setProgressLabel, + setDiscardLabel, +}: Props) => { + return useQuery({ + queryKey: ['get-all-improvements-for-review', page, selectedStatus], + queryFn: async () => { + const response = await axios.get( + `${GET_ALL_IMPROVEMENTS_FOR_USER}?page=${page}&status=${selectedStatus}` + ); + + const data = response.data; + + if (Number(page) === 1 && data.totalPages) { + setTotalPages(data.totalPages); + setImprovementData(data.articles); + } else if (data.articles) { + setImprovementData(prev => [...prev, ...data.articles]); + } + + if (Number(visit) === 1) { + if (data.publishedCount) { + setPublishedLabel(`Published(${data.publishedCount})`); + } + + if (data.progressCount) { + setProgressLabel(`Progress(${data.progressCount})`); + } + + if (data.discardCount) { + setDiscardLabel(`Discarded(${data.discardCount})`); + } + + setVisit(0); + } + + return data.articles as EditRequest[]; + }, + enabled: !!page, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetUserDetails.ts b/frontend/src/hooks/useGetUserDetails.ts new file mode 100644 index 0000000..47e1ca5 --- /dev/null +++ b/frontend/src/hooks/useGetUserDetails.ts @@ -0,0 +1,20 @@ +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { User } from "../type"; +import { GET_USER_DETAILS_API } from "../helper/APIUtils"; + +export const useGetUserDetails = (isConnected: boolean): UseQueryResult< +User, +AxiosError +>=>{ + + return useQuery({ + queryKey: ['get-user-details-by-id'], + queryFn: async () => { + const response = await axios.get(`${GET_USER_DETAILS_API}`); + + return response.data.profile as User; + }, + enabled: !!isConnected, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useGetUserSocialCircle.ts b/frontend/src/hooks/useGetUserSocialCircle.ts new file mode 100644 index 0000000..53a2a97 --- /dev/null +++ b/frontend/src/hooks/useGetUserSocialCircle.ts @@ -0,0 +1,37 @@ + +import { useQuery } from '@tanstack/react-query'; +import axios from 'axios'; +import { GET_SOCIALS } from '../helper/APIUtils'; +import { User } from '../type'; + +interface Props { + type: string; + articleId?: string; + social_user_id?: string; +} + +export const useGetUserSocials = ({ + type, + articleId, + social_user_id, +}: Props) => { + return useQuery({ + queryKey: ['get-user-socials', type, articleId, social_user_id], + queryFn: async () => { + let url = articleId + ? `${GET_SOCIALS}?type=${type}&articleId=${articleId}` + : `${GET_SOCIALS}?type=${type}`; + + if (social_user_id && social_user_id !== '') { + url = `${url}&social_user_id=${social_user_id}`; + } + + console.log('Request Url', url); + + const response = await axios.get(url); + + return response.data.followers as User[]; + }, + enabled: !!type, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useGetYearlyReadReport.ts b/frontend/src/hooks/useGetYearlyReadReport.ts new file mode 100644 index 0000000..d4ad7a9 --- /dev/null +++ b/frontend/src/hooks/useGetYearlyReadReport.ts @@ -0,0 +1,32 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import axios from 'axios'; +import {YearStatus} from '../type'; +import {GET_YEARLY_READ_REPORT} from '../helper/APIUtils'; + +export const useGetAuthorYearlyReadReport = ( + user_id: string, + selectedYear: number, + userId?: string, + others?: boolean, + isConnected?: boolean, +): UseQueryResult => { + return useQuery({ + queryKey: ['get-user-yearly-read-report', user_id, userId, others], + + queryFn: async () => { + if (selectedYear === -1) { + return []; + } + + let url = others + ? `${GET_YEARLY_READ_REPORT}?userId=${userId}&year=${selectedYear}` + : `${GET_YEARLY_READ_REPORT}?userId=${user_id}&year=${selectedYear}`; + + const response = await axios.get(url); + + return response.data.yearlyReads as YearStatus[]; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; diff --git a/frontend/src/hooks/useGetYearlyWriteReport.ts b/frontend/src/hooks/useGetYearlyWriteReport.ts new file mode 100644 index 0000000..4580ac6 --- /dev/null +++ b/frontend/src/hooks/useGetYearlyWriteReport.ts @@ -0,0 +1,32 @@ +import {useQuery, UseQueryResult} from '@tanstack/react-query'; +import axios from 'axios'; +import {YearStatus} from '../type'; +import {GET_YEARLY_WRITES_REPORT} from '../helper/APIUtils'; + +export const useGetAuthorYearlyWriteReport = ( + user_id: string, + selectedYear: number, + userId?: string, + others?: boolean, + isConnected?: boolean, +): UseQueryResult => { + return useQuery({ + queryKey: ['get-user-yearly-write-report', user_id, userId, others], + + queryFn: async () => { + if (selectedYear === -1) { + return []; + } + + let url = others + ? `${GET_YEARLY_WRITES_REPORT}?userId=${userId}&year=${selectedYear}` + : `${GET_YEARLY_WRITES_REPORT}?userId=${user_id}&year=${selectedYear}`; + + const response = await axios.get(url); + + return response.data.yearlyWrites as YearStatus[]; + }, + + enabled: !!isConnected && !!(!userId && others) && !!(!user_id && !others), + }); +}; diff --git a/frontend/src/hooks/useLikeArticle.ts b/frontend/src/hooks/useLikeArticle.ts new file mode 100644 index 0000000..9af32db --- /dev/null +++ b/frontend/src/hooks/useLikeArticle.ts @@ -0,0 +1,29 @@ +import axios, {AxiosError} from 'axios'; +import {ArticleData} from '../type'; +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import {LIKE_ARTICLE} from '../helper/APIUtils'; + +export const useLikeArticle = ( + articleId: number, +): UseMutationResult< + { + article: ArticleData; + likeStatus: boolean; + }, + AxiosError +> => { + return useMutation({ + mutationKey: ['update-like-status', articleId], + + mutationFn: async () => { + const res = await axios.post(LIKE_ARTICLE, { + article_id: articleId, + }); + + return res.data.data as { + article: ArticleData; + likeStatus: boolean; + }; + }, + }); +}; diff --git a/frontend/src/hooks/useMailVerification.ts b/frontend/src/hooks/useMailVerification.ts new file mode 100644 index 0000000..b517c85 --- /dev/null +++ b/frontend/src/hooks/useMailVerification.ts @@ -0,0 +1,26 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { VERIFICATION_MAIL_API } from "../helper/APIUtils"; + +type VerificationReq = { + email: string; + token: string +} +export const useVerificationMailMutation = (): UseMutationResult< + string, + AxiosError, + VerificationReq + +>=>{ + return useMutation({ + mutationKey: ['send-verification-mail'], + mutationFn: async (req: VerificationReq) => { + const res = await axios.post(VERIFICATION_MAIL_API, { + email: req.email, + token: req.token, + }); + + return res.data.message as string; + }, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/usePostArticle.ts b/frontend/src/hooks/usePostArticle.ts new file mode 100644 index 0000000..90d7301 --- /dev/null +++ b/frontend/src/hooks/usePostArticle.ts @@ -0,0 +1,32 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import {ArticleData, Category} from '../type'; +import axios, {AxiosError} from 'axios'; +import {POST_ARTICLE} from '../helper/APIUtils'; + +type PostReq = { + title: string; + authorName: string; + authorId: string; + content: string; + tags: Category[]; + imageUtils: string[]; + description: string; + pb_recordId: string; + allow_podcast: boolean; + language: string; +}; + +export const usePostArticleData = (): UseMutationResult< + ArticleData, + AxiosError, + PostReq +> => { + return useMutation({ + mutationKey: ['create-post-key'], + mutationFn: async (data: PostReq) => { + const response = await axios.post(POST_ARTICLE, data); + // console.log(article); + return response.data.newArticle as ArticleData; + }, + }); +}; diff --git a/frontend/src/hooks/useRequestArticleEdit.ts b/frontend/src/hooks/useRequestArticleEdit.ts new file mode 100644 index 0000000..41d8e05 --- /dev/null +++ b/frontend/src/hooks/useRequestArticleEdit.ts @@ -0,0 +1,36 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { REQUEST_EDIT } from "../helper/APIUtils"; + +type ArticleEditReq = { + articleId: string; + reason: string; + articleRecordId: string; +}; + +export const useRequestArticleEdit = (): UseMutationResult< + string, + AxiosError, + ArticleEditReq +>=>{ + return useMutation({ + mutationKey: ['submit-edit-request'], + mutationFn: async ({ + articleId, + reason, + articleRecordId, + }:ArticleEditReq) => { + const res = await axios.post( + REQUEST_EDIT, + { + article_id: articleId, + edit_reason: reason, + article_recordId: articleRecordId, + } + ); + + return res.data.message as string; + }, + + }); +} diff --git a/frontend/src/hooks/useResendVerification.ts b/frontend/src/hooks/useResendVerification.ts new file mode 100644 index 0000000..f7e27f2 --- /dev/null +++ b/frontend/src/hooks/useResendVerification.ts @@ -0,0 +1,20 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {RESEND_VERIFICATION} from '../helper/APIUtils'; + +export const useRequestVerification = (): UseMutationResult< + string, + AxiosError, + {email: string} +> => { + return useMutation({ + mutationKey: ['resend-verification-mail'], + mutationFn: async ({email}: {email: string}) => { + const res = await axios.post(RESEND_VERIFICATION, { + email: email, + }); + + return res.data.message as string; + }, + }); +}; diff --git a/frontend/src/hooks/useSaveArticle.ts b/frontend/src/hooks/useSaveArticle.ts new file mode 100644 index 0000000..50fa5da --- /dev/null +++ b/frontend/src/hooks/useSaveArticle.ts @@ -0,0 +1,26 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import { SAVE_ARTICLE } from "../helper/APIUtils"; +import axios, { AxiosError } from "axios"; + + +export const useSaveArticle = (articleId: number): UseMutationResult< + any, + AxiosError +>=>{ + + return useMutation({ + mutationKey: [`update-save-article`, articleId], + mutationFn: async () => { + + const res = await axios.post( + SAVE_ARTICLE, + { + article_id: articleId, + }, + ); + + return res.data as any; + }, + + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useSendOtp.ts b/frontend/src/hooks/useSendOtp.ts new file mode 100644 index 0000000..4f773ba --- /dev/null +++ b/frontend/src/hooks/useSendOtp.ts @@ -0,0 +1,19 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { SEND_OTP } from "../helper/APIUtils"; + +export const useSendOtpMutation = ():UseMutationResult< + string, + AxiosError, + {email: string} +> =>{ + return useMutation({ + mutationKey: ['forgot-password-otp'], + mutationFn: async ({email}: {email: string}) => { + const res = await axios.post(SEND_OTP, { + email: email, + }); + return res.data.otp as string; + }, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useSubmitEditRequestMutation.ts b/frontend/src/hooks/useSubmitEditRequestMutation.ts new file mode 100644 index 0000000..9d00126 --- /dev/null +++ b/frontend/src/hooks/useSubmitEditRequestMutation.ts @@ -0,0 +1,44 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { REQUEST_EDIT } from "../helper/APIUtils"; + +type SubmitEditRequestParams = { + articleId: string; + reason: string; + articleRecordId: string; + userToken: string; +}; + +export const useSubmitEditRequest = ():UseMutationResult< + string, + AxiosError, + SubmitEditRequestParams +> => { + return useMutation({ + mutationKey: ["submit-edit-request"], + + mutationFn: async ({ + articleId, + reason, + articleRecordId, + userToken, + }: SubmitEditRequestParams) => { + const res = await axios.post( + REQUEST_EDIT, + { + article_id: articleId, + edit_reason: reason, + article_recordId: articleRecordId, + }, + { + headers: { + Authorization: `Bearer ${userToken}`, + }, + } + ); + + return res.data.message as string; + }, + + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useSubmitImprovement.ts b/frontend/src/hooks/useSubmitImprovement.ts new file mode 100644 index 0000000..fdfd0c1 --- /dev/null +++ b/frontend/src/hooks/useSubmitImprovement.ts @@ -0,0 +1,35 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import {ArticleData} from '../type'; +import axios, {AxiosError} from 'axios'; +import {SUBMIT_IMPROVEMENT} from '../helper/APIUtils'; + +type SubmitReq = { + edited_content: string; + recordId: string; + requestId: string; + imageUtils: string[]; +}; +export const useSubmitImprovement = (): UseMutationResult< + ArticleData, + AxiosError, + SubmitReq +> => { + return useMutation({ + mutationKey: ['submiit-improvemeny-key'], + mutationFn: async ({ + edited_content, + recordId, + requestId, + imageUtils, + }: SubmitReq) => { + const response = await axios.post(SUBMIT_IMPROVEMENT, { + requestId: requestId, + edited_content: edited_content, + pb_recordId: recordId, + imageUtils: imageUtils, + }); + // console.log(article); + return response.data.newArticle as ArticleData; + }, + }); +}; diff --git a/frontend/src/hooks/useSubmitReport.ts b/frontend/src/hooks/useSubmitReport.ts new file mode 100644 index 0000000..029dd73 --- /dev/null +++ b/frontend/src/hooks/useSubmitReport.ts @@ -0,0 +1,47 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { SUBMIT_REPORT } from "../helper/APIUtils"; + +type SubmitReportParams = { + articleId?: number | null; + podcastId?: number | null; + commentId?: number | null; + reportedBy: number; + reasonId: number; + authorId: number; +}; + +export const useSubmitReport = ():UseMutationResult< +any, +AxiosError, +SubmitReportParams +> => { + return useMutation({ + mutationKey: ["submit-report"], + mutationFn: async ({ + articleId, + podcastId, + commentId, + reportedBy, + reasonId, + authorId, + }: SubmitReportParams) => { + + const res = await axios.post( + SUBMIT_REPORT, + { + articleId: podcastId ? null : articleId, + podcastId: podcastId, + commentId: commentId, + reportedBy: reportedBy, + reasonId: reasonId, + authorId: authorId, + }, + ); + + return { data: res.data }; + }, + + + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useSubmitSuggestedChanges.ts b/frontend/src/hooks/useSubmitSuggestedChanges.ts new file mode 100644 index 0000000..9ee8728 --- /dev/null +++ b/frontend/src/hooks/useSubmitSuggestedChanges.ts @@ -0,0 +1,51 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { SUBMIT_SUGGESTED_CHANGES } from "../helper/APIUtils"; + +type SubmitSuggestedChangesParams = { + article: string; + title: string; + userId: number; + authorName: string; + articleId: string; + tags: string[]; + imageUtils: any; + description: string; +}; + +export const useSubmitSuggestedChanges = (): UseMutationResult< +any, +AxiosError, +SubmitSuggestedChangesParams +> => { + return useMutation({ + mutationKey: ["submit-post-key"], + + mutationFn: async ({ + article, + title, + userId, + authorName, + articleId, + tags, + imageUtils, + description, + }: SubmitSuggestedChangesParams) => { + const response = await axios.post( + SUBMIT_SUGGESTED_CHANGES, + { + title, + userId, + authorName, + articleId, + content: article, + tags, + imageUtils, + description, + } + ); + + return { data: response.data.newArticle}; + }, + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateFollowStatus.ts b/frontend/src/hooks/useUpdateFollowStatus.ts new file mode 100644 index 0000000..6b8a685 --- /dev/null +++ b/frontend/src/hooks/useUpdateFollowStatus.ts @@ -0,0 +1,26 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { FOLLOW_USER } from "../helper/APIUtils"; + + +export const useUpdateFollowStatus = (): UseMutationResult< + boolean, + AxiosError, + string +>=>{ + return useMutation({ + mutationKey: ['update-follow-status'], + + mutationFn: async (userid: string) => { + + const res = await axios.post( + FOLLOW_USER, + { + followUserId: userid, + }, + ); + return res.data.followStatus as boolean; + }, + }); + +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdatePassword.ts b/frontend/src/hooks/useUpdatePassword.ts new file mode 100644 index 0000000..2224fdc --- /dev/null +++ b/frontend/src/hooks/useUpdatePassword.ts @@ -0,0 +1,28 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import { UPDATE_USER_PASSWORD } from "../helper/APIUtils"; +import axios, { AxiosError } from "axios"; + +type UpdateReq = { + old_password: string; + new_password: string; +} +export const useUpdatePassword = (): UseMutationResult< + any, + AxiosError, + UpdateReq +>=>{ + + return useMutation({ + mutationKey: ['user-password-updation'], + mutationFn: async (req: UpdateReq) => { + const response = await axios.put( + `${UPDATE_USER_PASSWORD}`, + { + old_password: req.old_password, + new_password: req.new_password, + }, + ); + return response.data as any; + }, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateProfileImage.ts b/frontend/src/hooks/useUpdateProfileImage.ts new file mode 100644 index 0000000..2eccdcf --- /dev/null +++ b/frontend/src/hooks/useUpdateProfileImage.ts @@ -0,0 +1,24 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { UPDATE_PROFILE_IMAGE } from "../helper/APIUtils"; + + +export const useUpdateProfileImage = (): UseMutationResult< + any, + AxiosError, + string +>=>{ + return useMutation({ + mutationKey: ['user-profile-image-updation'], + mutationFn: async (profileImageUrl: string) => { + const response = await axios.post( + `${UPDATE_PROFILE_IMAGE}`, + { + profileImageUrl, + } + ); + return response.data as any; + }, + + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateReadEvent.ts b/frontend/src/hooks/useUpdateReadEvent.ts new file mode 100644 index 0000000..b2d788d --- /dev/null +++ b/frontend/src/hooks/useUpdateReadEvent.ts @@ -0,0 +1,24 @@ +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import axios, { AxiosError } from "axios"; +import { UPDATE_READ_EVENT } from "../helper/APIUtils"; + +export const useUpdateReadEvent = (articleId: number): UseMutationResult< +any, +AxiosError +>=>{ + + return useMutation({ + mutationKey: ['update-read-event-status', articleId], + + mutationFn: async () => { + + const res = await axios.post( + UPDATE_READ_EVENT, + { + article_id: articleId, + } + ); + return res.data as any; + } + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateUserContactDetail.ts b/frontend/src/hooks/useUpdateUserContactDetail.ts new file mode 100644 index 0000000..7599dca --- /dev/null +++ b/frontend/src/hooks/useUpdateUserContactDetail.ts @@ -0,0 +1,24 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {UPDATE_USER_CONTACT_DETAILS} from '../helper/APIUtils'; + +type UpdateReq = { + phone: string; + email: string; +}; +export const useUpdateUserContactDetail = (): UseMutationResult< + any, + AxiosError, + UpdateReq +> => { + return useMutation({ + mutationKey: ['user-contact-details-updation'], + mutationFn: async (req: UpdateReq) => { + const response = await axios.put(`${UPDATE_USER_CONTACT_DETAILS}`, { + phone: req.phone, + email: req.email, + }); + return response.data as any; + }, + }); +}; diff --git a/frontend/src/hooks/useUpdateUserGeneralDetails.ts b/frontend/src/hooks/useUpdateUserGeneralDetails.ts new file mode 100644 index 0000000..f4b447e --- /dev/null +++ b/frontend/src/hooks/useUpdateUserGeneralDetails.ts @@ -0,0 +1,30 @@ +import axios, { AxiosError } from "axios"; +import { UPDATE_USER_GENERAL_DETAILS } from "../helper/APIUtils"; +import { useMutation, UseMutationResult } from "@tanstack/react-query"; + + +type UpdateReq ={ + username: string; + about: string; +} +export const useUpdateUserGeneralDetails = ():UseMutationResult< +any, +AxiosError, +UpdateReq +>=>{ + + return useMutation({ + mutationKey: ['user-general-details-updation'], + mutationFn: async (req: UpdateReq) => { + const response = await axios.put( + `${UPDATE_USER_GENERAL_DETAILS}`, + { + username: req.username, + about: req.about, + } + ); + return response.data as any; + }, + + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateUserProfDetails.ts b/frontend/src/hooks/useUpdateUserProfDetails.ts new file mode 100644 index 0000000..9c68017 --- /dev/null +++ b/frontend/src/hooks/useUpdateUserProfDetails.ts @@ -0,0 +1,31 @@ +import axios, { AxiosError } from "axios"; +import { UPDATE_USER_PROFESSIONAL_DETAILS } from "../helper/APIUtils"; +import { useMutation, UseMutationResult } from "@tanstack/react-query"; + + +type UpdateReq ={ + specialization: string; + qualification: string; + experience: string; +} +export const useUpdateUserProfDetails = ():UseMutationResult< +any, +AxiosError, +UpdateReq +>=>{ + + return useMutation({ + mutationKey: ['user-professional-details-updation'], + mutationFn: async (req: UpdateReq) => { + const response = await axios.put( + `${UPDATE_USER_PROFESSIONAL_DETAILS}`, + { + specialization: req.specialization, + qualification: req.qualification, + experience: req.experience, + } + ); + return response.data as any; + }, + }); +} \ No newline at end of file diff --git a/frontend/src/hooks/useUpdateViewCount.ts b/frontend/src/hooks/useUpdateViewCount.ts new file mode 100644 index 0000000..45e5f3d --- /dev/null +++ b/frontend/src/hooks/useUpdateViewCount.ts @@ -0,0 +1,20 @@ +import axios, {AxiosError} from 'axios'; +import {ArticleData} from '../type'; +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import {UPDATE_VIEW_COUNT} from '../helper/APIUtils'; + +export const useUpdateViewCount = (articleId: number): UseMutationResult< + ArticleData, + AxiosError +> => { + return useMutation({ + mutationKey: ['update-view-count', articleId], + mutationFn: async () => { + const res = await axios.post(UPDATE_VIEW_COUNT, { + article_id: articleId, + }); + + return res.data.article as ArticleData; + }, + }); +}; diff --git a/frontend/src/hooks/useUploadArticlePocketbase.ts b/frontend/src/hooks/useUploadArticlePocketbase.ts new file mode 100644 index 0000000..27bba7f --- /dev/null +++ b/frontend/src/hooks/useUploadArticlePocketbase.ts @@ -0,0 +1,25 @@ +import {useMutation} from '@tanstack/react-query'; +import axios from 'axios'; +import {ArticleData, PocketBaseResponse} from '../type'; +import {UPLOAD_ARTICLE_TO_POCKETBASE} from '../helper/APIUtils'; + +interface Props { + title: string; + articleData?: ArticleData; + htmlContent: string; +} + +export const useUploadArticleToPocketbase = () => { + return useMutation({ + mutationKey: ['upload-article-to-pocketbase-key'], + mutationFn: async ({title, articleData, htmlContent}: Props) => { + const response = await axios.post(UPLOAD_ARTICLE_TO_POCKETBASE, { + title: title, + htmlContent: htmlContent, + record_id: articleData ? articleData.pb_recordId : null, + }); + + return response.data as PocketBaseResponse; + }, + }); +}; diff --git a/frontend/hooks/useUploadAudio.tsx b/frontend/src/hooks/useUploadAudio.tsx similarity index 100% rename from frontend/hooks/useUploadAudio.tsx rename to frontend/src/hooks/useUploadAudio.tsx diff --git a/frontend/hooks/useUploadImage.tsx b/frontend/src/hooks/useUploadImage.tsx similarity index 100% rename from frontend/hooks/useUploadImage.tsx rename to frontend/src/hooks/useUploadImage.tsx diff --git a/frontend/src/hooks/useUserLogin.ts b/frontend/src/hooks/useUserLogin.ts new file mode 100644 index 0000000..2d9915b --- /dev/null +++ b/frontend/src/hooks/useUserLogin.ts @@ -0,0 +1,30 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {LOGIN_API} from '../helper/APIUtils'; +import {User} from '../type'; + +type LoginReq = { + email: string; + password: string; + fcmToken: string; +}; + +const loginFunc = async ({email, password, fcmToken}: LoginReq) => { + const res = await axios.post(LOGIN_API, { + email, + password, + fcmToken, + }); + return res.data.user as User; +}; + +export const useLoginMutation = (): UseMutationResult< + User, + AxiosError, + LoginReq +> => { + return useMutation({ + mutationKey: ['user_login'], + mutationFn: loginFunc, + }); +}; diff --git a/frontend/src/hooks/useUserLogout.ts b/frontend/src/hooks/useUserLogout.ts new file mode 100644 index 0000000..e25cacd --- /dev/null +++ b/frontend/src/hooks/useUserLogout.ts @@ -0,0 +1,13 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {USER_LOGOUT} from '../helper/APIUtils'; + +export const useUserLogout = (): UseMutationResult => { + return useMutation({ + mutationKey: ['user-logout'], + mutationFn: async () => { + const response = await axios.post(`${USER_LOGOUT}`, {}); + return response.data as any; + }, + }); +}; diff --git a/frontend/src/hooks/useUserRegistration.ts b/frontend/src/hooks/useUserRegistration.ts new file mode 100644 index 0000000..b99ef38 --- /dev/null +++ b/frontend/src/hooks/useUserRegistration.ts @@ -0,0 +1,34 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {REGISTRATION_API} from '../helper/APIUtils'; +import {Contactdetail} from '../type'; + +type RegdReq = { + user_name: string; + user_handle: string; + email: string; + password: string; + isDoctor: boolean; + Profile_image: string | null; + specialization?: string | null; + qualification?: string | null; + Years_of_experience?: string | null; + + contact_detail?: Contactdetail; +}; + +const regdFunc = async (request: RegdReq) => { + const res = await axios.post(REGISTRATION_API, request); + return res.data.token as string; +}; + +export const useRegdMutation = (): UseMutationResult< + string, + AxiosError, + RegdReq +> => { + return useMutation({ + mutationKey: ['user_registration'], + mutationFn: regdFunc, + }); +}; diff --git a/frontend/src/hooks/useVerifyOtp.ts b/frontend/src/hooks/useVerifyOtp.ts new file mode 100644 index 0000000..20206da --- /dev/null +++ b/frontend/src/hooks/useVerifyOtp.ts @@ -0,0 +1,24 @@ +import {useMutation, UseMutationResult} from '@tanstack/react-query'; +import axios, {AxiosError} from 'axios'; +import {CHECK_OTP} from '../helper/APIUtils'; + +type VerifyReq = { + email: string; + otp: string; +}; +export const useVerifyOtpMutation = (): UseMutationResult< + string, + AxiosError, + VerifyReq +> => { + return useMutation({ + mutationKey: ['verify-otp'], + mutationFn: async (req: VerifyReq) => { + const res = await axios.post(CHECK_OTP, { + email: req.email, + otp: req.otp, + }); + return res.data.message as string; + }, + }); +}; diff --git a/frontend/src/screens/HomeScreen.tsx b/frontend/src/screens/HomeScreen.tsx index f793de0..ef1aba4 100644 --- a/frontend/src/screens/HomeScreen.tsx +++ b/frontend/src/screens/HomeScreen.tsx @@ -26,7 +26,6 @@ import { ARTICLE_TAGS_API, GET_PROFILE_API, PROD_URL, - REPOST_ARTICLE, REQUEST_EDIT, } from '../helper/APIUtils'; import FilterModal from '../components/FilterModal'; @@ -49,6 +48,7 @@ import {useFocusEffect} from '@react-navigation/native'; import InactiveUserModal from '../components/InactiveUserModal'; import {StatusBar} from 'expo-status-bar'; import {wp} from '../helper/Metric'; +import {useRepostArticle} from '../hooks/useArticleRepost'; // Here The purpose of using Redux is to maintain filter state throughout the app session. globally const HomeScreen = ({navigation}: HomeScreenProps) => { @@ -61,6 +61,8 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { const [repostItem, setRepostItem] = useState(null); const [selectCategoryList, setSelectCategoryList] = useState([]); const [filterLoading, setFilterLoading] = useState(false); + + const {mutate: repost, isPending: repostPending} = useRepostArticle(); const { filteredArticles, searchedArticles, @@ -193,79 +195,109 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { }; const handleRepostAction = (item: ArticleData) => { - if (isConnected) { - setRepostItem(item); - repostMutation.mutate({ - articleId: Number(item._id), - }); - } else { + if (!isConnected) { Snackbar.show({ text: 'Please check your network connection', duration: Snackbar.LENGTH_SHORT, }); + return; } - }; - const repostMutation = useMutation({ - mutationKey: ['repost-user-article'], - mutationFn: async ({ - articleId, - }: // authorId, - { - articleId: number; - // authorId: string; - }) => { - if (user_token === '') { - Alert.alert('No token found'); - return; - } - const res = await axios.post( - REPOST_ARTICLE, - { - articleId: articleId, - }, - { - headers: { - Authorization: `Bearer ${user_token}`, - }, - }, - ); + repost(Number(item._id), { + onSuccess: () => { + refetch(); - return res.data as any; - }, - onSuccess: () => { - refetch(); - Snackbar.show({ - text: 'Article reposted in your feed', - duration: Snackbar.LENGTH_SHORT, - }); + Snackbar.show({ + text: 'Article reposted in your feed', + duration: Snackbar.LENGTH_SHORT, + }); - if (repostItem) { const body = { type: 'repost', userId: user_id, - authorId: repostItem.authorId, - postId: repostItem._id, - articleRecordId: repostItem.pb_recordId, + authorId: item.authorId, + postId: item._id, + articleRecordId: item.pb_recordId, message: { title: `${user_handle} reposted`, - message: `${repostItem.title}`, + message: `${item.title}`, }, authorMessage: { title: `${user_handle} reposted your article`, - message: `${repostItem.title}`, + message: `${item.title}`, }, }; socket.emit('notification', body); - } - }, + }, - onError: error => { - console.log('Repost Error', error); - Alert.alert('Internal server error, try again!'); - }, - }); + onError: error => { + console.log('Repost Error', error); + Alert.alert('Internal server error, try again!'); + }, + }); + }; + + // const repostMutation = useMutation({ + // mutationKey: ['repost-user-article'], + // mutationFn: async ({ + // articleId, + // }: // authorId, + // { + // articleId: number; + // // authorId: string; + // }) => { + // if (user_token === '') { + // Alert.alert('No token found'); + // return; + // } + // const res = await axios.post( + // REPOST_ARTICLE, + // { + // articleId: articleId, + // }, + // { + // headers: { + // Authorization: `Bearer ${user_token}`, + // }, + // }, + // ); + + // return res.data as any; + // }, + // onSuccess: () => { + // refetch(); + // Snackbar.show({ + // text: 'Article reposted in your feed', + // duration: Snackbar.LENGTH_SHORT, + // }); + + // if (repostItem) { + // const body = { + // type: 'repost', + // userId: user_id, + // authorId: repostItem.authorId, + // postId: repostItem._id, + // articleRecordId: repostItem.pb_recordId, + // message: { + // title: `${user_handle} reposted`, + // message: `${repostItem.title}`, + // }, + // authorMessage: { + // title: `${user_handle} reposted your article`, + // message: `${repostItem.title}`, + // }, + // }; + + // socket.emit('notification', body); + // } + // }, + + // onError: error => { + // console.log('Repost Error', error); + // Alert.alert('Internal server error, try again!'); + // }, + // }); const submitEditRequestMutation = useMutation({ mutationKey: ['submit-edit-request'], @@ -351,22 +383,21 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { // Update Redux State Variables console.log('enter'); if (selectCategoryList.length > 0) { - // console.log("enter") + // console.log("enter") dispatch(setSelectedTags({selectedTags: selectCategoryList})); } else { - //console.log("enter ele", articleCategories); + //console.log("enter ele", articleCategories); dispatch( setSelectedTags({ selectedTags: articleCategories, }), ); - } - if(sortingType && sortingType !== ''){ - console.log("Sort type", sortType); - dispatch(setSortType({sortType: sortingType})); + if (sortingType && sortingType !== '') { + console.log('Sort type', sortType); + dispatch(setSortType({sortType: sortingType})); } if (sortingType && sortingType !== '') { @@ -480,19 +511,17 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { } }; - const listData = useMemo(() => { - if (searchMode) return searchedArticles; + const listData = useMemo(() => { + if (searchMode) return searchedArticles; - const filtered = filteredArticles.filter( - (article:ArticleData) => - article.tags && - article.tags.some( - tag => tag.name === selectedCategory?.name, - ), - ); + const filtered = filteredArticles.filter( + (article: ArticleData) => + article.tags && + article.tags.some(tag => tag.name === selectedCategory?.name), + ); - return filtered.sort(() => Math.random() - 0.5); -}, [searchMode, searchedArticles, filteredArticles, selectedCategory]); + return filtered.sort(() => Math.random() - 0.5); + }, [searchMode, searchedArticles, filteredArticles, selectedCategory]); if (!articleData || articleData.length === 0) { return ( @@ -604,7 +633,7 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { ))} - + { @@ -622,8 +651,6 @@ const HomeScreen = ({navigation}: HomeScreenProps) => { ); } - - return ( { {((filteredArticles && filteredArticles.length > 0) || searchedArticles.length > 0) && ( item._id.toString()} contentContainerStyle={styles.flatListContentContainer} diff --git a/frontend/src/screens/PodcastPlayer.tsx b/frontend/src/screens/PodcastPlayer.tsx index 63b68a7..58bffa3 100644 --- a/frontend/src/screens/PodcastPlayer.tsx +++ b/frontend/src/screens/PodcastPlayer.tsx @@ -8,9 +8,9 @@ import axios from 'axios'; import Snackbar from 'react-native-snackbar'; import {UPLOAD_PODCAST} from '../helper/APIUtils'; -import useUploadImage from '../../hooks/useUploadImage'; +import useUploadImage from '../hooks/useUploadImage'; import ImageResizer from '@bam.tech/react-native-image-resizer'; -import useUploadAudio from '../../hooks/useUploadAudio'; +import useUploadAudio from '../hooks/useUploadAudio'; import Slider from '@react-native-community/slider'; import {useAudioPlayer} from 'expo-audio'; diff --git a/frontend/src/screens/ProfileEditScreen.tsx b/frontend/src/screens/ProfileEditScreen.tsx index b12947a..bcd225f 100644 --- a/frontend/src/screens/ProfileEditScreen.tsx +++ b/frontend/src/screens/ProfileEditScreen.tsx @@ -36,7 +36,7 @@ import { ImagePickerResponse, } from 'react-native-image-picker'; import ImageResizer from '@bam.tech/react-native-image-resizer'; -import useUploadImage from '../../hooks/useUploadImage'; +import useUploadImage from '../hooks/useUploadImage'; import {showAlert} from '../store/alertSlice'; import Snackbar from 'react-native-snackbar'; // eslint-disable-next-line @typescript-eslint/no-require-imports diff --git a/frontend/src/screens/ProfileScreen.tsx b/frontend/src/screens/ProfileScreen.tsx index 0449728..d0bf764 100644 --- a/frontend/src/screens/ProfileScreen.tsx +++ b/frontend/src/screens/ProfileScreen.tsx @@ -10,7 +10,6 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'; import ProfileHeader from '../components/ProfileHeader'; import { GET_PROFILE_API, - REPOST_ARTICLE, UPDATE_VIEW_COUNT, } from '../helper/APIUtils'; import {ArticleData, ProfileScreenProps, User} from '../type'; @@ -21,6 +20,7 @@ import {useFocusEffect} from '@react-navigation/native'; import Snackbar from 'react-native-snackbar'; import {useSocket} from '../../SocketContext'; import {setUserHandle} from '../store/UserSlice'; +import { useRepostArticle } from '../hooks/useArticleRepost'; const ProfileScreen = ({navigation}: ProfileScreenProps) => { const {user_handle, user_id, user_token} = useSelector( @@ -36,6 +36,8 @@ const ProfileScreen = ({navigation}: ProfileScreenProps) => { const socket = useSocket(); const dispatch = useDispatch(); + const {mutate: repost, isPending: repostPending} = useRepostArticle(); + const { data: user, refetch, @@ -138,83 +140,111 @@ const ProfileScreen = ({navigation}: ProfileScreenProps) => { ); // eslint-disable-next-line react-hooks/exhaustive-deps - const handleRepostAction = (item: ArticleData) => { - if (isConnected) { - // updateLikeMutation.mutate(); - setRepostItem(item); - - repostMutation.mutate({ - articleId: Number(item._id), - }); - } else { + const handleRepostAction = (item: ArticleData) => { + if (!isConnected) { Snackbar.show({ text: 'Please check your network connection', duration: Snackbar.LENGTH_SHORT, }); + return; } - }; - const repostMutation = useMutation({ - mutationKey: ['repost-user-article'], - mutationFn: async ({ - articleId, - }: // authorId, - { - articleId: number; - // authorId: string; - }) => { - if (user_token === '') { - Alert.alert('No token found'); - return; - } - const res = await axios.post( - REPOST_ARTICLE, - { - articleId: articleId, - }, - { - headers: { - Authorization: `Bearer ${user_token}`, - }, - }, - ); + repost(Number(item._id), { + onSuccess: () => { + refetch(); - return res.data as any; - }, - onSuccess: () => { - refetch(); - Snackbar.show({ - text: 'Article reposted in your feed', - duration: Snackbar.LENGTH_SHORT, - }); + Snackbar.show({ + text: 'Article reposted in your feed', + duration: Snackbar.LENGTH_SHORT, + }); - if (repostItem) { - //emitNotification(repostItem); - socket.emit('notification', { + const body = { type: 'repost', userId: user_id, - authorId: repostItem.authorId, - postId: repostItem._id, - articleRecordId: repostItem.pb_recordId, + authorId: item.authorId, + postId: item._id, + articleRecordId: item.pb_recordId, message: { title: `${user_handle} reposted`, - message: `${repostItem.title}`, + message: `${item.title}`, }, authorMessage: { title: `${user_handle} reposted your article`, - message: `${repostItem.title}`, + message: `${item.title}`, }, - }); - } + }; - // Emit notification - }, + socket.emit('notification', body); + }, - onError: error => { - console.log('Repost Error', error); - Alert.alert('Internal server error, try again!'); - }, - }); + onError: error => { + console.log('Repost Error', error); + Alert.alert('Internal server error, try again!'); + }, + }); + }; + + // const repostMutation = useMutation({ + // mutationKey: ['repost-user-article'], + // mutationFn: async ({ + // articleId, + // }: // authorId, + // { + // articleId: number; + // // authorId: string; + // }) => { + // if (user_token === '') { + // Alert.alert('No token found'); + // return; + // } + // const res = await axios.post( + // REPOST_ARTICLE, + // { + // articleId: articleId, + // }, + // { + // headers: { + // Authorization: `Bearer ${user_token}`, + // }, + // }, + // ); + + // return res.data as any; + // }, + // onSuccess: () => { + // refetch(); + // Snackbar.show({ + // text: 'Article reposted in your feed', + // duration: Snackbar.LENGTH_SHORT, + // }); + + // if (repostItem) { + // //emitNotification(repostItem); + // socket.emit('notification', { + // type: 'repost', + // userId: user_id, + // authorId: repostItem.authorId, + // postId: repostItem._id, + // articleRecordId: repostItem.pb_recordId, + // message: { + // title: `${user_handle} reposted`, + // message: `${repostItem.title}`, + // }, + // authorMessage: { + // title: `${user_handle} reposted your article`, + // message: `${repostItem.title}`, + // }, + // }); + // } + + // // Emit notification + // }, + + // onError: error => { + // console.log('Repost Error', error); + // Alert.alert('Internal server error, try again!'); + // }, + // }); // eslint-disable-next-line react-hooks/exhaustive-deps const handleReportAction = (item: ArticleData) => { navigation.navigate('ReportScreen', { diff --git a/frontend/src/screens/SocialScreen.tsx b/frontend/src/screens/SocialScreen.tsx index ecc1498..d1ce280 100644 --- a/frontend/src/screens/SocialScreen.tsx +++ b/frontend/src/screens/SocialScreen.tsx @@ -55,7 +55,7 @@ export default function Socialcreen({navigation, route}: SocialScreenProps) { Authorization: `Bearer ${user_token}`, }, }); - console.log('Response', response.data.followers); + // console.log('Response', response.data.followers); return response.data.followers as User[]; }, }); diff --git a/frontend/src/screens/SplashScreen.tsx b/frontend/src/screens/SplashScreen.tsx index f8c65f6..de230ce 100644 --- a/frontend/src/screens/SplashScreen.tsx +++ b/frontend/src/screens/SplashScreen.tsx @@ -11,7 +11,7 @@ import {SplashScreenProp} from '../type'; import {useDispatch} from 'react-redux'; import {retrieveItem, KEYS, clearStorage} from '../helper/Utils'; import {setUserId, setUserToken, setUserHandle} from '../store/UserSlice'; -import { useCheckTokenStatus } from '@/hooks/useGetTokenStatus'; +import { useCheckTokenStatus } from '@/src/hooks/useGetTokenStatus'; export default function SplashScreen({navigation}: SplashScreenProp) { const opacity = useSharedValue(0); diff --git a/frontend/src/screens/UserProfileScreen.tsx b/frontend/src/screens/UserProfileScreen.tsx index 6b32911..296cfdd 100644 --- a/frontend/src/screens/UserProfileScreen.tsx +++ b/frontend/src/screens/UserProfileScreen.tsx @@ -10,7 +10,6 @@ import ProfileHeader from '../components/ProfileHeader'; import { FOLLOW_USER, PROD_URL, - REPOST_ARTICLE, REQUEST_EDIT, UPDATE_VIEW_COUNT, } from '../helper/APIUtils'; @@ -22,6 +21,7 @@ import Loader from '../components/Loader'; import {useFocusEffect} from '@react-navigation/native'; import Snackbar from 'react-native-snackbar'; import {useSocket} from '../../SocketContext'; +import {useRepostArticle} from '../hooks/useArticleRepost'; const UserProfileScreen = ({navigation, route}: UserProfileScreenProp) => { const {authorId, author_handle} = route.params; @@ -38,6 +38,8 @@ const UserProfileScreen = ({navigation, route}: UserProfileScreenProp) => { //const [authorId, setAuthorId] = useState(''); const socket = useSocket(); + const {mutate: repost, isPending: repostPending} = useRepostArticle(); + const { data: user, refetch, @@ -69,19 +71,47 @@ const UserProfileScreen = ({navigation, route}: UserProfileScreenProp) => { // eslint-disable-next-line react-hooks/exhaustive-deps const handleRepostAction = (item: ArticleData) => { - if (isConnected) { - // updateLikeMutation.mutate(); - setRepostItem(item); - - repostMutation.mutate({ - articleId: Number(item._id), - }); - } else { + if (!isConnected) { Snackbar.show({ text: 'Please check your network connection', duration: Snackbar.LENGTH_SHORT, }); + return; } + + repost(Number(item._id), { + onSuccess: () => { + refetch(); + + Snackbar.show({ + text: 'Article reposted in your feed', + duration: Snackbar.LENGTH_SHORT, + }); + + const body = { + type: 'repost', + userId: user_id, + authorId: item.authorId, + postId: item._id, + articleRecordId: item.pb_recordId, + message: { + title: `${user_handle} reposted`, + message: `${item.title}`, + }, + authorMessage: { + title: `${user_handle} reposted your article`, + message: `${item.title}`, + }, + }; + + socket.emit('notification', body); + }, + + onError: error => { + console.log('Repost Error', error); + Alert.alert('Internal server error, try again!'); + }, + }); }; const onArticleViewed = ({ @@ -107,66 +137,66 @@ const UserProfileScreen = ({navigation, route}: UserProfileScreenProp) => { } }; - const repostMutation = useMutation({ - mutationKey: ['repost-user-article'], - mutationFn: async ({ - articleId, - }: // authorId, - { - articleId: number; - // authorId: string; - }) => { - if (user_token === '') { - Alert.alert('No token found'); - return; - } - const res = await axios.post( - REPOST_ARTICLE, - { - articleId: articleId, - }, - { - headers: { - Authorization: `Bearer ${user_token}`, - }, - }, - ); - - return res.data as any; - }, - onSuccess: () => { - //refetch(); - Snackbar.show({ - text: 'Article reposted in your feed', - duration: Snackbar.LENGTH_SHORT, - }); - - // Emit notification - if (repostItem) { - //emitNotification(repostItem); - socket.emit('notification', { - type: 'repost', - userId: user_id, - authorId: repostItem.authorId, - postId: repostItem._id, - articleRecordId: repostItem.pb_recordId, - message: { - title: `${user_handle} reposted`, - message: `${repostItem.title}`, - }, - authorMessage: { - title: `${user_handle} reposted your article`, - message: `${repostItem.title}`, - }, - }); - } - }, - - onError: error => { - console.log('Repost Error', error); - Alert.alert('Internal server error, try again!'); - }, - }); + // const repostMutation = useMutation({ + // mutationKey: ['repost-user-article'], + // mutationFn: async ({ + // articleId, + // }: // authorId, + // { + // articleId: number; + // // authorId: string; + // }) => { + // if (user_token === '') { + // Alert.alert('No token found'); + // return; + // } + // const res = await axios.post( + // REPOST_ARTICLE, + // { + // articleId: articleId, + // }, + // { + // headers: { + // Authorization: `Bearer ${user_token}`, + // }, + // }, + // ); + + // return res.data as any; + // }, + // onSuccess: () => { + // //refetch(); + // Snackbar.show({ + // text: 'Article reposted in your feed', + // duration: Snackbar.LENGTH_SHORT, + // }); + + // // Emit notification + // if (repostItem) { + // //emitNotification(repostItem); + // socket.emit('notification', { + // type: 'repost', + // userId: user_id, + // authorId: repostItem.authorId, + // postId: repostItem._id, + // articleRecordId: repostItem.pb_recordId, + // message: { + // title: `${user_handle} reposted`, + // message: `${repostItem.title}`, + // }, + // authorMessage: { + // title: `${user_handle} reposted your article`, + // message: `${repostItem.title}`, + // }, + // }); + // } + // }, + + // onError: error => { + // console.log('Repost Error', error); + // Alert.alert('Internal server error, try again!'); + // }, + // }); const updateViewCountMutation = useMutation({ mutationKey: ['update-view-count-user-profile'], @@ -553,7 +583,7 @@ const styles = StyleSheet.create({ overflow: 'hidden', }, scrollViewContentContainer: { - // paddingHorizontal: 10, + // paddingHorizontal: 10, marginTop: 16, }, flatListContentContainer: { diff --git a/frontend/src/screens/article/PreviewScreen.tsx b/frontend/src/screens/article/PreviewScreen.tsx index 6376396..fd7f55d 100644 --- a/frontend/src/screens/article/PreviewScreen.tsx +++ b/frontend/src/screens/article/PreviewScreen.tsx @@ -32,7 +32,7 @@ import { UPLOAD_IMPROVEMENT_TO_POCKETBASE, } from '../../helper/APIUtils'; import {useDispatch, useSelector} from 'react-redux'; -import useUploadImage from '../../../hooks/useUploadImage'; +import useUploadImage from '../../hooks/useUploadImage'; import {setSuggestion} from '../../store/dataSlice'; import Snackbar from 'react-native-snackbar'; import AutoHeightWebView from '@brown-bear/react-native-autoheight-webview'; @@ -229,6 +229,7 @@ export default function PreviewScreen({navigation, route}: PreviewScreenProp) { description: description, pb_recordId: recordId, allow_podcast: true, + language: "en-IN" }, { headers: { diff --git a/frontend/src/screens/auth/NewPasswordScreen.tsx b/frontend/src/screens/auth/NewPasswordScreen.tsx index 0715fbf..eb5a1b9 100644 --- a/frontend/src/screens/auth/NewPasswordScreen.tsx +++ b/frontend/src/screens/auth/NewPasswordScreen.tsx @@ -22,6 +22,7 @@ import AntDesign from '@expo/vector-icons/AntDesign'; import {ON_PRIMARY_COLOR, PRIMARY_COLOR} from '@/src/helper/Theme'; import Entypo from '@expo/vector-icons/Entypo'; import Icon from '@expo/vector-icons/Ionicons'; +import {useChangePasswordMutation} from '@/src/hooks/useChangePassword'; export default function NewPasswordScreen({ navigation, @@ -36,6 +37,8 @@ export default function NewPasswordScreen({ const [secureTextEntry, setSecureTextEntry] = useState(true); const [secureNewTextEntry, setSecureNewTextEntry] = useState(true); + const {mutate: changePassword, isPending} = useChangePasswordMutation(); + const handleSecureEntryClickEvent = () => { setSecureTextEntry(!secureTextEntry); }; @@ -44,35 +47,71 @@ export default function NewPasswordScreen({ setSecureNewTextEntry(!secureNewTextEntry); }; - const handlePasswordSubmit = () => { - if (!password || password.length === 0) { - //setError({...error, new: true}); - //setErrorText({...errorText, new: 'Please give a password'}); - Alert.alert('Please give a password'); - setErrorMessage('Please give a password'); - return; - } else if (!passwordVerify) { - //setError({...error, new: true}); - Alert.alert('Please enter a valid password'); - setErrorMessage('Please enter a valid password'); - return; - } else if (!confirmPassword || confirmPassword.length === 0) { - //setError({...error, confirm: true}); - Alert.alert('Please confirm your password'); - setErrorMessage('Please confirm your password'); - return; - } else if (password !== confirmPassword) { - // setError({...error, confirm: true}); - Alert.alert('confirmation password does not match the new password'); - setErrorMessage('confirmation password does not match the new password'); - return; - } else { - //navigation.navigate('LoginScreen'); - setErrorMessage(null); - changePasswordMutation.mutate(); - } + const handlePasswordSubmit = () => { + const showError = (msg: string) => { + Alert.alert(msg); + setErrorMessage(msg); }; + if (!password?.trim()) { + return showError('Please give a password'); + } + + if (!passwordVerify) { + return showError('Please enter a valid password'); + } + + if (!confirmPassword?.trim()) { + return showError('Please confirm your password'); + } + + if (password !== confirmPassword) { + return showError( + 'Confirmation password does not match the new password', + ); + } + + setErrorMessage(null); + + changePassword( + { + email, + newPassword: password, + }, + { + onSuccess: () => { + Alert.alert('Password reset successfully'); + navigation.navigate('LoginScreen'); + }, + + onError: (error: AxiosError) => { + if (error.response) { + switch (error.response.status) { + case 400: + Alert.alert('Error', 'User not found'); + break; + + case 402: + Alert.alert( + 'Error', + 'New password should not be same as old password', + ); + break; + + default: + Alert.alert( + 'Error', + 'Something went wrong. Please try again.', + ); + } + } else { + Alert.alert('Error', 'Something went wrong. Please try again.'); + } + }, + }, + ); +}; + const handlePassword = e => { let pass = e; setErrorMessage(null); @@ -97,234 +136,230 @@ export default function NewPasswordScreen({ } }; - const changePasswordMutation = useMutation({ - mutationKey: ['generate-new-password'], - mutationFn: async () => { - const res = await axios.post(CHANGE_PASSWORD_API, { - email: email, - newPassword: password, - }); - return res.data as any; - }, - onSuccess: () => { - Alert.alert('Password reset successfully'); - navigation.navigate('LoginScreen'); - }, + // const changePasswordMutation = useMutation({ + // mutationKey: ['generate-new-password'], + // mutationFn: async () => { + // const res = await axios.post(CHANGE_PASSWORD_API, { + // email: email, + // newPassword: password, + // }); + // return res.data as any; + // }, + // onSuccess: () => { + // Alert.alert('Password reset successfully'); + // navigation.navigate('LoginScreen'); + // }, - onError: (error: AxiosError) => { - if (error.response) { - const statusCode = error.response.status; - switch (statusCode) { - case 400: - Alert.alert('Error', 'User not found'); - break; - case 402: - Alert.alert( - 'Error', - 'New password should not be same as old password', - ); - break; - default: - Alert.alert('Error', 'Something went wrong. Please try again.'); - } - } else { - Alert.alert('Error', 'Something went wrong. Please try again.'); - } - }, - }); + // onError: (error: AxiosError) => { + // if (error.response) { + // const statusCode = error.response.status; + // switch (statusCode) { + // case 400: + // Alert.alert('Error', 'User not found'); + // break; + // case 402: + // Alert.alert( + // 'Error', + // 'New password should not be same as old password', + // ); + // break; + // default: + // Alert.alert('Error', 'Something went wrong. Please try again.'); + // } + // } else { + // Alert.alert('Error', 'Something went wrong. Please try again.'); + // } + // }, + // }); - if (changePasswordMutation.isPending) { + if (isPending) { return ; } return ( - - - - - {/* Icon Circle */} - - - - - {/* Title & Subtitle */} - - Set your new password - + + + + + {/* Icon Circle */} + + + - {/* Inputs */} - - - - Password + {/* Title & Subtitle */} + + Set your new password - - - - - - + {/* Inputs */} + + + + Password + - - - Confirm your new password - + + + + + + - - - - - - - + + + Confirm your new password + - {/* Error Message */} - {errorMessage && ( - - {errorMessage} - - )} + + + + + + + - {/* Confirm Button */} - - - + {/* Error Message */} + {errorMessage && ( + + {errorMessage} + + )} - {/* Return Link */} - - - navigation.navigate('LoginScreen')} - > - Return to the login screen - - - - - - + {/* Confirm Button */} + + + + {/* Return Link */} + + + navigation.navigate('LoginScreen')}> + Return to the login screen + + + + + + ); } diff --git a/frontend/src/screens/auth/SignUpScreenFirst.tsx b/frontend/src/screens/auth/SignUpScreenFirst.tsx index 4bacc3b..e15c5bd 100644 --- a/frontend/src/screens/auth/SignUpScreenFirst.tsx +++ b/frontend/src/screens/auth/SignUpScreenFirst.tsx @@ -20,19 +20,19 @@ import {useMutation} from '@tanstack/react-query'; import axios, {AxiosError} from 'axios'; import Snackbar from 'react-native-snackbar'; import { - CHECK_USER_HANDLE, REGISTRATION_API, VERIFICATION_MAIL_API, } from '../../helper/APIUtils'; import EmailVerifiedModal from '../../components/VerifiedModal'; import ImageResizer from '@bam.tech/react-native-image-resizer'; import Loader from '../../components/Loader'; -import useUploadImage from '../../../hooks/useUploadImage'; +import useUploadImage from '../../hooks/useUploadImage'; import { ImageLibraryOptions, launchImageLibrary, ImagePickerResponse, } from 'react-native-image-picker'; +import { useCheckUserHandleAvailability } from '@/src/hooks/useCheckUserHandle'; // eslint-disable-next-line @typescript-eslint/no-require-imports let validator = require('email-validator'); @@ -46,11 +46,13 @@ const SignupPageFirst = ({navigation}: SignUpScreenFirstProp) => { const [role, setRole] = useState(''); const [verifyBtntext, setVerifyBtntxt] = useState('Request Verification'); const [verifiedModalVisible, setVerifiedModalVisible] = useState(false); - const [isHandleAvailable, setIsHandleAvailable] = useState(false); + // const [isHandleAvailable, setIsHandleAvailable] = useState(false); const [token, setToken] = useState(''); const [isFocus, setIsFocus] = useState(false); const [isSecureEntry, setIsSecureEntry] = useState(true); - const [error, setError] = useState(''); + //const [error, setError] = useState(''); + + const { data: checkhandle, isLoading } = useCheckUserHandleAvailability(username); const selectImage = async () => { const options: ImageLibraryOptions = { @@ -86,34 +88,34 @@ const SignupPageFirst = ({navigation}: SignUpScreenFirstProp) => { }); }; - const checkUserHandleAvailability = async handle => { - try { - const response = await axios.post(CHECK_USER_HANDLE, { - userHandle: username, - }); - if (response.data.status === true) { - setIsHandleAvailable(true); - console.log('User Handle ', isHandleAvailable); - } else { - setIsHandleAvailable(false); - console.log('User Handle ', isHandleAvailable); - setError(response.data.error); // Show the error message - } - } catch (err) { - console.error('Error checking user handle:', err); - setError('An error occurred while checking the user handle.'); - } - }; + // const checkUserHandleAvailability = async (handle:string) => { + // try { + // const response = await axios.post(CHECK_USER_HANDLE, { + // userHandle: username, + // }); + // if (response.data.status === true) { + // setIsHandleAvailable(true); + // console.log('User Handle ', isHandleAvailable); + // } else { + // setIsHandleAvailable(false); + // console.log('User Handle ', isHandleAvailable); + // setError(response.data.error); // Show the error message + // } + // } catch (err) { + // console.error('Error checking user handle:', err); + // setError('An error occurred while checking the user handle.'); + // } + // }; const handleUserHandleChange = text => { setUsername(text); - if (text.length > 2) { - // Check if the user handle is available every time the user types - checkUserHandleAvailability(text); - } else { - setIsHandleAvailable(true); - setError(''); - } + // if (text.length > 2) { + // // Check if the user handle is available every time the user types + // checkUserHandleAvailability(text); + // } else { + // setIsHandleAvailable(true); + // setError(''); + // } }; const userRegisterMutation = useMutation({ @@ -409,12 +411,12 @@ const SignupPageFirst = ({navigation}: SignUpScreenFirstProp) => { {/* Handle Error */} - {isHandleAvailable && ( + {checkhandle?.status === false && ( User handle is already in use. )} - + {isLoading && Checking...} {/* User Handle */}