From 25b14e58f4ba79e66c992efd513fbf64ba4a9b58 Mon Sep 17 00:00:00 2001 From: Arif-tekdi-technologies Date: Tue, 28 Jan 2025 17:21:38 +0530 Subject: [PATCH 1/5] Issue #PS-3384 feat: UI component for pop up of youth profile --- src/components/Header.tsx | 2 +- src/components/youthNet/BackHeader.tsx | 2 +- src/components/youthNet/DropDown.tsx | 39 ++++ src/components/youthNet/ProfileCard.tsx | 195 ++++++++++++++++++ src/components/youthNet/UserCard.tsx | 31 ++- src/components/youthNet/tempConfigs.ts | 12 ++ .../youthboard/student/[studentDetails].tsx | 98 +++++++++ src/pages/youthboard/villageDetails.tsx | 19 -- src/pages/youthboard/villages/index.tsx | 65 ++++-- 9 files changed, 421 insertions(+), 42 deletions(-) create mode 100644 src/components/youthNet/DropDown.tsx create mode 100644 src/components/youthNet/ProfileCard.tsx create mode 100644 src/pages/youthboard/student/[studentDetails].tsx delete mode 100644 src/pages/youthboard/villageDetails.tsx diff --git a/src/components/Header.tsx b/src/components/Header.tsx index ab6f8aca..9885eccd 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -67,7 +67,7 @@ const Header: React.FC = ({ toggleDrawer, openDrawer }) => { const tenant = localStorage.getItem('tenantName'); if (pathname !== `/user-profile/${userId}`) { if (tenant?.toLowerCase() === TENANT_DATA.YOUTHNET?.toLowerCase()) { - router.push(`youthboard/user-profile/${userId}`); + router.push(`/youthboard/user-profile/${userId}`); } else if ( tenant?.toLowerCase() === TENANT_DATA.SECOND_CHANCE_PROGRAM?.toLowerCase() diff --git a/src/components/youthNet/BackHeader.tsx b/src/components/youthNet/BackHeader.tsx index fd733cfc..52ffc688 100644 --- a/src/components/youthNet/BackHeader.tsx +++ b/src/components/youthNet/BackHeader.tsx @@ -3,7 +3,7 @@ import { Box, IconButton, Typography } from '@mui/material'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; interface BackHeaderProps { - headingOne: string; + headingOne?: string; headingTwo?: string; headingThree?: string; onBackClick?: () => void; diff --git a/src/components/youthNet/DropDown.tsx b/src/components/youthNet/DropDown.tsx new file mode 100644 index 00000000..3a0a9b9f --- /dev/null +++ b/src/components/youthNet/DropDown.tsx @@ -0,0 +1,39 @@ +import { MenuItem, FormControl, Select, InputLabel } from '@mui/material'; +import { useState } from 'react'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; + +interface DropdownProps { + name: string; + values: string[]; + onSelect: (value: string) => void; +} + +const Dropdown: React.FC = ({ name, values, onSelect }) => { + const [selectedValue, setSelectedValue] = useState(''); + + const handleChange = (event: any) => { + const value = event.target.value; + setSelectedValue(value); + onSelect(value); + }; + + return ( + + {name} + + + ); +}; + +export default Dropdown; diff --git a/src/components/youthNet/ProfileCard.tsx b/src/components/youthNet/ProfileCard.tsx new file mode 100644 index 00000000..371f27ac --- /dev/null +++ b/src/components/youthNet/ProfileCard.tsx @@ -0,0 +1,195 @@ +import React from 'react'; +import { + Avatar, + Box, + Typography, + List, + ListItem, + Divider, + Grid, +} from '@mui/material'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import { useTheme } from '@mui/material/styles'; + +type ProfileCardProps = { + name: string; + showAvtar?: boolean; + age?: string | number; + village?: string; + image?: string; + joinOn?: string; + isNew?: boolean; + showMore?: boolean; + totalCount?: number; + newRegistrations?: number; + onClick?: (name: string) => void; // Add onClick prop +}; + +const ProfileCard: React.FC = ({ + name, + age, + village, + image, + joinOn, + isNew, + showMore, + showAvtar, + totalCount, + newRegistrations, + onClick, +}) => { + const theme = useTheme(); + + return ( + onClick && onClick(name)} + > + + {showAvtar && ( + + {!image && name[0]} + + )} + + + {name} + + + + {age && ( + + {age} y/o • {village || joinOn} + + )} + {isNew && ( + + NEW + + )} + + {totalCount && ( + + {totalCount} + {newRegistrations && ( + + (+{newRegistrations}) + + )} + + )} + {showMore && ( + + )} + + + + + ); +}; + +type ProfileListProps = { + users: ProfileCardProps[]; + layout?: 'list' | 'grid'; // Added layout prop + onUserClick?: (name: string) => void; // Add onUserClick prop +}; + +export const ProfileList: React.FC = ({ + users, + layout = 'grid', + onUserClick, // Receive onUserClick prop +}) => { + return layout === 'grid' ? ( + + + {users.map((user, index) => ( + + + {' '} + {/* Pass onUserClick */} + + {index < users.length - 1} + + ))} + + + ) : ( + + {users.map((user, index) => ( + + + {index < users.length - 1} + + ))} + + ); +}; diff --git a/src/components/youthNet/UserCard.tsx b/src/components/youthNet/UserCard.tsx index 3e584066..5f29dd49 100644 --- a/src/components/youthNet/UserCard.tsx +++ b/src/components/youthNet/UserCard.tsx @@ -22,11 +22,7 @@ type UserCardProps = { showMore?: boolean; totalCount?: number; newRegistrations?: number; -}; - -type UserListProps = { - users: UserCardProps[]; - layout?: 'list' | 'grid'; // Added layout prop + onClick?: (name: string) => void; // Add onClick prop }; const UserCard: React.FC = ({ @@ -40,12 +36,14 @@ const UserCard: React.FC = ({ showAvtar, totalCount, newRegistrations, + onClick, }) => { const theme = useTheme(); + return ( = ({ }, }), }} + onClick={() => onClick && onClick(name)} > {showAvtar && ( @@ -99,10 +98,16 @@ const UserCard: React.FC = ({ - {age && ( + {age ? ( {age} y/o • {village || joinOn} + ) : ( + village && ( + + {village || joinOn} + + ) )} {isNew && ( = ({ ); }; +type UserListProps = { + users: UserCardProps[]; + layout?: 'list' | 'grid'; // Added layout prop + onUserClick?: (name: string) => void; // Add onUserClick prop +}; + export const UserList: React.FC = ({ users, layout = 'grid', + onUserClick, // Receive onUserClick prop }) => { return layout === 'grid' ? ( @@ -168,7 +180,8 @@ export const UserList: React.FC = ({ md={user.totalCount ? 12 : 6} lg={user.totalCount ? 12 : 4} > - + {' '} + {/* Pass onUserClick */} {index < users.length - 1 && } @@ -179,7 +192,7 @@ export const UserList: React.FC = ({ {users.map((user, index) => ( - + {index < users.length - 1 && } ))} diff --git a/src/components/youthNet/tempConfigs.ts b/src/components/youthNet/tempConfigs.ts index 2a97b62a..7d50c654 100644 --- a/src/components/youthNet/tempConfigs.ts +++ b/src/components/youthNet/tempConfigs.ts @@ -245,3 +245,15 @@ export const villageList = [ newRegistrations: 5, }, ]; + +export const DROPDOWN_NAME = 'Village'; +export const VILLAGE_OPTIONS = ['Shivare', 'Pune', 'Mumbai']; + +export const studentListDetails = [ + { + name: 'Ananya Gupta', + age: 'Shivare (Bhor, Pune, Maharashtra)', + showMore: true, + showAvtar: true, + }, +]; diff --git a/src/pages/youthboard/student/[studentDetails].tsx b/src/pages/youthboard/student/[studentDetails].tsx new file mode 100644 index 00000000..70ff26fe --- /dev/null +++ b/src/pages/youthboard/student/[studentDetails].tsx @@ -0,0 +1,98 @@ +import withRole from '@/components/withRole'; +import React, { useEffect, useState } from 'react'; +import { TENANT_DATA } from '../../../../app.config'; +import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; +import { useRouter } from 'next/router'; +import { useTranslation } from 'react-i18next'; +import { GetStaticPaths } from 'next'; +import Header from '@/components/Header'; +import BackHeader from '@/components/youthNet/BackHeader'; +import { Box, Typography } from '@mui/material'; +import { UserList } from '@/components/youthNet/UserCard'; +import { studentListDetails } from '@/components/youthNet/tempConfigs'; +import Profile from '@/components/youthNet/Profile'; +import { useTheme } from '@mui/material/styles'; + +const StudentDetails = () => { + const theme = useTheme(); + const { t } = useTranslation(); + const router = useRouter(); + const { studentDetails } = router.query; + + const [studentName, setStudentName] = useState(undefined); + + useEffect(() => { + if (Array.isArray(studentDetails)) { + setStudentName(studentDetails[0]); + } else { + setStudentName(studentDetails); + } + }, [studentDetails]); + + const handleBack = () => { + router.back(); + }; + + return ( + + +
+ + + + + + + + + + + + {t('YOUTHNET_PROFILE.PROFILE_DETAILS')} + + + + + ); +}; + +export async function getStaticProps({ locale }: any) { + return { + props: { + ...(await serverSideTranslations(locale, ['common'])), + // Will be passed to the page component as props + }, + }; +} + +export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => { + return { + paths: [], //indicates that no page needs be created at build time + fallback: 'blocking', //indicates the type of fallback + }; +}; + +export default withRole(TENANT_DATA.YOUTHNET)(StudentDetails); diff --git a/src/pages/youthboard/villageDetails.tsx b/src/pages/youthboard/villageDetails.tsx deleted file mode 100644 index 4745bb7c..00000000 --- a/src/pages/youthboard/villageDetails.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import withRole from '@/components/withRole'; -import React from 'react'; -import { TENANT_DATA } from '../../../app.config'; -import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; - -const villageDetails = () => { - return
villageDetails Page
; -}; - -export async function getStaticProps({ locale }: any) { - return { - props: { - ...(await serverSideTranslations(locale, ['common'])), - // Will be passed to the page component as props - }, - }; -} - -export default withRole(TENANT_DATA.YOUTHNET)(villageDetails); diff --git a/src/pages/youthboard/villages/index.tsx b/src/pages/youthboard/villages/index.tsx index 144a5116..5f72ca56 100644 --- a/src/pages/youthboard/villages/index.tsx +++ b/src/pages/youthboard/villages/index.tsx @@ -9,7 +9,9 @@ import SearchBar from '@/components/Searchbar'; import SortBy from '@/components/youthNet/SortBy'; import YouthAndVolunteers from '@/components/youthNet/YouthAndVolunteers'; import { + DROPDOWN_NAME, users, + VILLAGE_OPTIONS, villageList, youthList, } from '@/components/youthNet/tempConfigs'; @@ -17,10 +19,13 @@ import { UserList } from '@/components/youthNet/UserCard'; import DownloadIcon from '@mui/icons-material/Download'; import withRole from '@/components/withRole'; import { TENANT_DATA } from '../../../../app.config'; +import Dropdown from '@/components/youthNet/DropDown'; +import { useRouter } from 'next/router'; + const index = () => { const { t } = useTranslation(); const theme = useTheme(); - + const router = useRouter(); const [value, setValue] = useState(1); const [searchInput, setSearchInput] = useState(''); @@ -28,13 +33,18 @@ const index = () => { setValue(newValue); }; + const handleUserClick = (name: any) => { + console.log('Clicked user:', name); + router.push(`/youthboard/student/${name}`); + }; + return (
- + {value && ( @@ -86,15 +96,16 @@ const index = () => { @@ -112,7 +123,6 @@ const index = () => { fontSize: '16px', color: 'black', marginLeft: '2rem', - padding: '5px 5px', }} > 52 Villages @@ -123,7 +133,7 @@ const index = () => { display: 'flex', alignItems: 'center', cursor: 'pointer', - padding: '5px 5px', + pr: '20px', color: '#0D599E', '&:hover': { color: '#074d82', @@ -147,7 +157,7 @@ const index = () => { color: 'textSecondary', marginLeft: '2rem', cursor: 'pointer', - padding: '5px 5px', + pr: '20px', }} className="one-line-text" > @@ -158,9 +168,8 @@ const index = () => { sx={{ fontSize: '16px', color: 'textSecondary', - marginLeft: '2rem', cursor: 'pointer', - padding: '5px 5px', + pr: '20px', }} > Total Count (+ New Registrations today) @@ -168,7 +177,7 @@ const index = () => { @@ -186,7 +195,39 @@ const index = () => { mt: '15px', }} > - + console.log('Selected:', value)} + /> + + + + + + + )} From b57d1c8898a9c03167419404808d8827b4192fd5 Mon Sep 17 00:00:00 2001 From: Arif-tekdi-technologies Date: Tue, 28 Jan 2025 17:32:19 +0530 Subject: [PATCH 2/5] update --- src/components/youthNet/ProfileCard.tsx | 195 ------------------------ 1 file changed, 195 deletions(-) delete mode 100644 src/components/youthNet/ProfileCard.tsx diff --git a/src/components/youthNet/ProfileCard.tsx b/src/components/youthNet/ProfileCard.tsx deleted file mode 100644 index 371f27ac..00000000 --- a/src/components/youthNet/ProfileCard.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import React from 'react'; -import { - Avatar, - Box, - Typography, - List, - ListItem, - Divider, - Grid, -} from '@mui/material'; -import MoreVertIcon from '@mui/icons-material/MoreVert'; -import { useTheme } from '@mui/material/styles'; - -type ProfileCardProps = { - name: string; - showAvtar?: boolean; - age?: string | number; - village?: string; - image?: string; - joinOn?: string; - isNew?: boolean; - showMore?: boolean; - totalCount?: number; - newRegistrations?: number; - onClick?: (name: string) => void; // Add onClick prop -}; - -const ProfileCard: React.FC = ({ - name, - age, - village, - image, - joinOn, - isNew, - showMore, - showAvtar, - totalCount, - newRegistrations, - onClick, -}) => { - const theme = useTheme(); - - return ( - onClick && onClick(name)} - > - - {showAvtar && ( - - {!image && name[0]} - - )} - - - {name} - - - - {age && ( - - {age} y/o • {village || joinOn} - - )} - {isNew && ( - - NEW - - )} - - {totalCount && ( - - {totalCount} - {newRegistrations && ( - - (+{newRegistrations}) - - )} - - )} - {showMore && ( - - )} - - - - - ); -}; - -type ProfileListProps = { - users: ProfileCardProps[]; - layout?: 'list' | 'grid'; // Added layout prop - onUserClick?: (name: string) => void; // Add onUserClick prop -}; - -export const ProfileList: React.FC = ({ - users, - layout = 'grid', - onUserClick, // Receive onUserClick prop -}) => { - return layout === 'grid' ? ( - - - {users.map((user, index) => ( - - - {' '} - {/* Pass onUserClick */} - - {index < users.length - 1} - - ))} - - - ) : ( - - {users.map((user, index) => ( - - - {index < users.length - 1} - - ))} - - ); -}; From fa8cb956245f648e64633afde0c1bd9aa826e32b Mon Sep 17 00:00:00 2001 From: Arif-tekdi-technologies Date: Tue, 28 Jan 2025 17:37:03 +0530 Subject: [PATCH 3/5] fixes --- src/pages/youthboard/student/[studentDetails].tsx | 1 - src/pages/youthboard/villages/index.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/youthboard/student/[studentDetails].tsx b/src/pages/youthboard/student/[studentDetails].tsx index 70ff26fe..552c279c 100644 --- a/src/pages/youthboard/student/[studentDetails].tsx +++ b/src/pages/youthboard/student/[studentDetails].tsx @@ -9,7 +9,6 @@ import Header from '@/components/Header'; import BackHeader from '@/components/youthNet/BackHeader'; import { Box, Typography } from '@mui/material'; import { UserList } from '@/components/youthNet/UserCard'; -import { studentListDetails } from '@/components/youthNet/tempConfigs'; import Profile from '@/components/youthNet/Profile'; import { useTheme } from '@mui/material/styles'; diff --git a/src/pages/youthboard/villages/index.tsx b/src/pages/youthboard/villages/index.tsx index 5f72ca56..a8d89fda 100644 --- a/src/pages/youthboard/villages/index.tsx +++ b/src/pages/youthboard/villages/index.tsx @@ -22,7 +22,7 @@ import { TENANT_DATA } from '../../../../app.config'; import Dropdown from '@/components/youthNet/DropDown'; import { useRouter } from 'next/router'; -const index = () => { +const Index = () => { const { t } = useTranslation(); const theme = useTheme(); const router = useRouter(); @@ -244,4 +244,4 @@ export async function getStaticProps({ locale }: any) { }; } -export default withRole(TENANT_DATA.YOUTHNET)(index); +export default withRole(TENANT_DATA.YOUTHNET)(Index); From 575ab134e22fbe5a8ff2f289217c19e6dfa72bd9 Mon Sep 17 00:00:00 2001 From: Arif-tekdi-technologies Date: Wed, 29 Jan 2025 11:50:55 +0530 Subject: [PATCH 4/5] update --- .../student/{[studentDetails].tsx => [id].tsx} | 11 +++++------ src/services/youthNet/SurveyYouthService.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) rename src/pages/youthboard/student/{[studentDetails].tsx => [id].tsx} (92%) diff --git a/src/pages/youthboard/student/[studentDetails].tsx b/src/pages/youthboard/student/[id].tsx similarity index 92% rename from src/pages/youthboard/student/[studentDetails].tsx rename to src/pages/youthboard/student/[id].tsx index 552c279c..76cd0d29 100644 --- a/src/pages/youthboard/student/[studentDetails].tsx +++ b/src/pages/youthboard/student/[id].tsx @@ -16,17 +16,17 @@ const StudentDetails = () => { const theme = useTheme(); const { t } = useTranslation(); const router = useRouter(); - const { studentDetails } = router.query; + const { id } = router.query; const [studentName, setStudentName] = useState(undefined); useEffect(() => { - if (Array.isArray(studentDetails)) { - setStudentName(studentDetails[0]); + if (Array.isArray(id)) { + setStudentName(id[0]); } else { - setStudentName(studentDetails); + setStudentName(id); } - }, [studentDetails]); + }, [id]); const handleBack = () => { router.back(); @@ -63,7 +63,6 @@ const StudentDetails = () => { > => { if (USE_MOCK) { @@ -17,3 +19,17 @@ export const fetchSurveyData = async (): Promise => { return false; } }; + +export const fetchStudentData = async (): Promise => { + if (USE_STUDENT_MOCK) { + return MOCK_SURVEY_CONFIG.surveyAvailable; + } + + try { + const response = await axios.get(`${API_BASE_URL}/survey`); + return response?.data?.surveyAvailable || false; + } catch (error) { + console.error('Error fetching survey data:', error); + return false; + } +}; From 06a8f45b90212446c9ead5ee49a38fc9627d0e2c Mon Sep 17 00:00:00 2001 From: Arif-tekdi-technologies Date: Wed, 29 Jan 2025 11:55:05 +0530 Subject: [PATCH 5/5] fixes --- src/services/youthNet/SurveyYouthService.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/youthNet/SurveyYouthService.ts b/src/services/youthNet/SurveyYouthService.ts index 70954a44..438df33a 100644 --- a/src/services/youthNet/SurveyYouthService.ts +++ b/src/services/youthNet/SurveyYouthService.ts @@ -20,13 +20,13 @@ export const fetchSurveyData = async (): Promise => { } }; -export const fetchStudentData = async (): Promise => { +export const fetchStudentData = async (): Promise => { if (USE_STUDENT_MOCK) { - return MOCK_SURVEY_CONFIG.surveyAvailable; + return USE_STUDENT_MOCK; } try { - const response = await axios.get(`${API_BASE_URL}/survey`); + const response = await axios.get(`${API_BASE_URL}/studentList`); return response?.data?.surveyAvailable || false; } catch (error) { console.error('Error fetching survey data:', error);