Skip to content

Commit 5f60f82

Browse files
DebatreyaNavvneetKCopilotArnavSharma005heydoyouknowme0
authored
Refactor/faculty (#411)
This pull request introduces the "areas of interest" field to faculty profiles across the application, enhancing the display and management of faculty expertise. It also includes improvements to the faculty profile UI, adds department information, and makes minor corrections to health center data and translations. **Faculty Profile Enhancements:** * Added support for the `areasOfInterest` field to faculty profiles, including database queries, profile editing, and display on both faculty list and individual faculty pages. This allows faculty to specify and showcase their research areas and specializations. ([app/[locale]/@modals/(.)profile/edit/page.tsxR59](diffhunk://#diff-e73212c94224fb2541821a5e5cdf5880f9ecace5d712ec5cd8dff6e590ded805R59), [app/[locale]/@modals/(.)profile/edit/page.tsxR84](diffhunk://#diff-e73212c94224fb2541821a5e5cdf5880f9ecace5d712ec5cd8dff6e590ded805R84), [app/[locale]/faculty-and-staff/page.tsxR339-R343](diffhunk://#diff-73d9b8e5183a03609e638663514db195677d4e964b2ba2898d7ad4aa250d81d6R339-R343), [app/[locale]/faculty-and-staff/utils.tsxR115](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dR115), [app/[locale]/faculty-and-staff/utils.tsxL288-R317](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dL288-R317), [app/[locale]/faculty-and-staff/page.tsxR407-R488](diffhunk://#diff-73d9b8e5183a03609e638663514db195677d4e964b2ba2898d7ad4aa250d81d6R407-R488)) * Updated the profile edit form to handle `areasOfInterest` as a comma-separated list, with user guidance and validation. ([app/[locale]/@modals/(.)profile/edit/client-utils.tsxR19](diffhunk://#diff-7c2e4d7020e011706a88acc0afb6b98c2056a5adb5900f07977925b7e4ec1b03R19), [app/[locale]/@modals/(.)profile/edit/client-utils.tsxR130-R166](diffhunk://#diff-7c2e4d7020e011706a88acc0afb6b98c2056a5adb5900f07977925b7e4ec1b03R130-R166)) **UI/UX Improvements:** * Enhanced the faculty profile UI by displaying department names, improving the edit button appearance, and refining the layout for research areas and external profile links. ([app/[locale]/faculty-and-staff/utils.tsxR128-R132](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dR128-R132), [app/[locale]/faculty-and-staff/utils.tsxL196-R202](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dL196-R202), [app/[locale]/faculty-and-staff/utils.tsxL206-R227](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dL206-R227), [app/[locale]/faculty-and-staff/page.tsxR365-R371](diffhunk://#diff-73d9b8e5183a03609e638663514db195677d4e964b2ba2898d7ad4aa250d81d6R365-R371), [app/[locale]/faculty-and-staff/page.tsxL369-R396](diffhunk://#diff-73d9b8e5183a03609e638663514db195677d4e964b2ba2898d7ad4aa250d81d6L369-R396), [app/[locale]/faculty-and-staff/utils.tsxL321-R346](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dL321-R346)) * Separated the display of intellectual contribution counts into its own section for better clarity and organization. ([app/[locale]/faculty-and-staff/utils.tsxR355-R377](diffhunk://#diff-3e362b10e143377150343a08121115b31eeefe1081b2d3cdc3bb5551eaec6b4dR355-R377)) **Internationalization (i18n):** * Added translation keys and values for "Areas of Interest" in both English and Hindi, ensuring the new field is properly localized. [[1]](diffhunk://#diff-8ee4c65eaaf735c33bd37bf76d2a87fb76d02b7928096cc26db6364694988ceeR333) [[2]](diffhunk://#diff-912c4f60653cc2c8d00fda0b21a7a65ab1c3e1c3f65007e1f211f40c951596b8R342) [[3]](diffhunk://#diff-f021560af3d5a0f14642131f53f3141ab31d57c62b232272a5a097673e427d49R201) **Minor Fixes and Cleanups:** * Fixed formatting and consistency in the health center section, including hospital names and timings. ([app/[locale]/institute/sections/health-centre/page.tsxL36-R36](diffhunk://#diff-38944ec42877c43150f9f89c1ae5bbc6a073d69363647186f6abfa9696cdcecfL36-R36), [app/[locale]/institute/sections/health-centre/page.tsxL305-R309](diffhunk://#diff-38944ec42877c43150f9f89c1ae5bbc6a073d69363647186f6abfa9696cdcecfL305-R309), [app/[locale]/institute/sections/health-centre/page.tsxL318-R328](diffhunk://#diff-38944ec42877c43150f9f89c1ae5bbc6a073d69363647186f6abfa9696cdcecfL318-R328), [app/[locale]/institute/sections/health-centre/page.tsxL490-R503](diffhunk://#diff-38944ec42877c43150f9f89c1ae5bbc6a073d69363647186f6abfa9696cdcecfL490-R503)) * Cleaned up translation files for better readability and consistency. --------- Co-authored-by: Navneet Kaur <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: ArnavSharma005 <[email protected]> Co-authored-by: heydoyouknowme0 <[email protected]>
1 parent 1351bf8 commit 5f60f82

File tree

8 files changed

+121
-27
lines changed

8 files changed

+121
-27
lines changed

app/[locale]/@modals/(.)profile/edit/client-utils.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { CardContent, CardFooter } from '~/components/ui';
1717
import {
1818
FormControl,
19+
FormDescription,
1920
FormField,
2021
FormItem,
2122
FormLabel,
@@ -126,6 +127,43 @@ const renderFields = <T extends Record<string, any>>(
126127
.replace(/^./, (str: string) => str.toUpperCase())
127128
.trim();
128129

130+
// Handle areasOfInterest array field
131+
if (fieldName === 'areasOfInterest') {
132+
return (
133+
<FormField
134+
key={fieldName}
135+
control={formControl}
136+
name={fieldName as unknown as FieldPath<T>}
137+
render={({ field }) => (
138+
<FormItem className="md:col-span-2">
139+
<FormLabel>{label}</FormLabel>
140+
<FormControl>
141+
<Textarea
142+
id={fieldName}
143+
className="w-full"
144+
placeholder="Enter areas of interest separated by commas"
145+
required={!isOptional}
146+
value={
147+
Array.isArray(field.value)
148+
? (field.value as string[]).join(', ')
149+
: (field.value as string) ?? ''
150+
}
151+
onChange={(e) => {
152+
field.onChange(e.target.value);
153+
}}
154+
onBlur={field.onBlur}
155+
/>
156+
</FormControl>
157+
<FormMessage />
158+
<FormDescription>
159+
Enter multiple areas of interest separated by commas
160+
</FormDescription>
161+
</FormItem>
162+
)}
163+
/>
164+
);
165+
}
166+
129167
// Check if it's an enum field
130168
if (fieldSchema._def.typeName === ZodFirstPartyTypeKind.ZodEnum) {
131169
const enumValues = fieldSchema._def.values;

app/[locale]/@modals/(.)profile/edit/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default async function Page({
5656
linkedInId: true,
5757
googleScholarId: true,
5858
researchGateId: true,
59+
areasOfInterest: true,
5960
},
6061
with: {
6162
person: {
@@ -80,6 +81,7 @@ export default async function Page({
8081
telephone: result.person.telephone,
8182
alternateCountryCode: result.person.alternateCountryCode ?? undefined,
8283
alternateTelephone: result.person.alternateTelephone ?? undefined,
84+
areasOfInterest: result.areasOfInterest ?? [],
8385
};
8486
});
8587
if (!personalDetails) {

app/[locale]/faculty-and-staff/utils.tsx

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ async function FacultyOrStaffComponent({
112112
linkedInId: true,
113113
researchGateId: true,
114114
scopusId: true,
115+
areasOfInterest: true,
115116
},
116117
with: {
117118
person: {
@@ -124,6 +125,11 @@ async function FacultyOrStaffComponent({
124125
alternateCountryCode: true,
125126
},
126127
},
128+
department: {
129+
columns: {
130+
name: true,
131+
},
132+
},
127133
},
128134
extras: {
129135
publications: db
@@ -193,7 +199,7 @@ async function FacultyOrStaffComponent({
193199
<>
194200
<section className="container mb-6 mt-24 grid gap-3 xl:grid-cols-[calc(50%-0.75rem),0%,calc(50%-0.75rem)]">
195201
<article className="flex flex-grow flex-col rounded-2xl bg-shade-light p-5 drop-shadow-[0_4px_24px_rgba(0,43,91,0.1)]">
196-
<h2 className="mb-0 text-primary-700 max-xl:mr-[8rem]">
202+
<h2 className="mb-2 text-primary-700 max-xl:mr-[8rem]">
197203
{facultyDescription.person.name}
198204
</h2>
199205
<span className="flex items-center justify-between">
@@ -203,16 +209,22 @@ async function FacultyOrStaffComponent({
203209
{id && (
204210
<Button
205211
variant="primary"
206-
className="mr-5 !rounded-sm pr-1 max-xl:hidden"
212+
className="mr-10 flex gap-2 !rounded-sm px-2 py-1 max-xl:hidden"
207213
asChild
208214
>
209-
<Link href={`/${locale}/profile/edit?personal=true`}>
210-
<MdOutlineEdit size={24} className="cursor-pointer" />
211-
Edit Profile
215+
<Link
216+
href={`/${locale}/profile/edit?personal=true`}
217+
className="text-lg"
218+
>
219+
<MdOutlineEdit size={22} className="cursor-pointer" />
220+
Edit
212221
</Link>
213222
</Button>
214223
)}
215224
</span>
225+
<h5 className="mb-4 text-neutral-900">
226+
{facultyDescription.department?.name ?? ''}
227+
</h5>
216228
{id && (
217229
<Button
218230
variant="primary"
@@ -285,25 +297,24 @@ async function FacultyOrStaffComponent({
285297
</section>
286298
{/* Faculty Intellectual Contribution counts */}
287299
<article className="rounded-2xl drop-shadow-[0_4px_24px_rgba(0,43,91,0.1)] max-xl:pt-3 xl:bg-shade-light xl:p-5">
288-
<ul className="grid h-full grid-cols-3 gap-5 xl:ml-16">
289-
{Object.entries(text.intellectualContributions).map(
290-
([key, value]) => (
291-
<li
292-
key={key}
293-
className="flex h-full flex-col justify-around rounded-2xl bg-primary-700 p-3 max-xl:aspect-square"
294-
>
295-
<h4 className="my-auto text-center text-shade-light">
296-
{facultyDescription[
297-
key as keyof typeof text.intellectualContributions
298-
] ?? 0}
299-
</h4>
300-
<p className="mb-auto text-center font-light text-shade-light">
301-
{value}
302-
</p>
303-
</li>
304-
)
305-
)}
306-
</ul>
300+
<div className="ml-16">
301+
<h4>Research Areas and Specialization</h4>
302+
{facultyDescription.areasOfInterest &&
303+
facultyDescription.areasOfInterest.length > 0 && (
304+
<ScrollArea className="h-44 w-full">
305+
<ul className="list-inside space-y-2 text-lg marker:text-primary-700">
306+
{facultyDescription.areasOfInterest.map((area, index) => (
307+
<li key={index}>
308+
<span className="font-bold text-primary-700">
309+
&gt;{' '}
310+
</span>{' '}
311+
{area}
312+
</li>
313+
))}
314+
</ul>
315+
</ScrollArea>
316+
)}
317+
</div>
307318
</article>
308319
</section>
309320
{/* Faculty links to external profiles */}
@@ -318,15 +329,21 @@ async function FacultyOrStaffComponent({
318329
return (
319330
<Link
320331
key={key}
321-
className="flex aspect-square flex-col justify-evenly rounded-2xl bg-shade-light drop-shadow-[0_4px_24px_rgba(0,43,91,0.1)] md:w-[23%] lg:w-[20%]"
322-
href={facultyDescription[key] ?? ''}
332+
className="flex flex-col justify-evenly rounded-2xl bg-shade-light drop-shadow-[0_4px_24px_rgba(0,43,91,0.1)] md:w-[25%] lg:w-[22%]"
333+
href={
334+
!facultyDescription[key]
335+
? ''
336+
: facultyDescription[key]!.startsWith('https')
337+
? facultyDescription[key]!
338+
: `https://${facultyDescription[key]!}`
339+
}
323340
>
324341
<Image
325342
alt={key}
326343
src={`faculty-and-staff/${key}.svg`}
327344
height={0}
328345
width={0}
329-
className="mx-auto h-[50%] w-[50%]"
346+
className="mx-auto aspect-square h-[50%] w-[50%] object-contain"
330347
/>
331348
<h5 className="mx-auto">{value}</h5>
332349
</Link>
@@ -335,6 +352,29 @@ async function FacultyOrStaffComponent({
335352
})}
336353
</section>
337354

355+
{/* Faculty Intlectual Contribution counts */}
356+
<section className="container mb-6 justify-between max-md:gap-6">
357+
<ul className="grid h-full grid-cols-3 gap-5">
358+
{Object.entries(text.intellectualContributions).map(
359+
([key, value]) => (
360+
<li
361+
key={key}
362+
className="flex h-full flex-col justify-around rounded-2xl bg-primary-700 p-3 py-6"
363+
>
364+
<h4 className="my-auto text-center text-shade-light">
365+
{facultyDescription[
366+
key as keyof typeof text.intellectualContributions
367+
] ?? 0}
368+
</h4>
369+
<p className="mb-auto text-center font-light text-shade-light">
370+
{value}
371+
</p>
372+
</li>
373+
)
374+
)}
375+
</ul>
376+
</section>
377+
338378
{/* Faculty Professional Details */}
339379
<section className="container flex gap-y-4 max-md:flex-col md:h-[28rem] md:gap-x-4 lg:gap-x-8">
340380
{/* Left Side Tabs */}

i18n/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ const text: Translations = {
330330
researchGateId: 'Research Gate',
331331
scopusId: 'Scopus',
332332
},
333+
areasOfInterest: 'Areas of Interest',
333334
intellectualContributions: {
334335
publications: 'PUBLICATIONS',
335336
continuingEducation: 'CONTINUING EDUCATION',

i18n/hi.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ const text: Translations = {
339339
researchGateId: 'रिसर्च गेट',
340340
scopusId: 'स्कोपस',
341341
},
342+
areasOfInterest: 'रुचि के क्षेत्र',
342343
intellectualContributions: {
343344
publications: 'प्रकाशन',
344345
continuingEducation: 'निरंतर शिक्षा',

i18n/translations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export interface Translations {
198198
researchGateId: string;
199199
scopusId: string;
200200
};
201+
areasOfInterest: string;
201202
intellectualContributions: {
202203
publications: string;
203204
continuingEducation: string;

lib/schemas/faculty-profile.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ export const facultyPersonalDetailsSchema = z.object({
166166
.regex(/^\d{5,15}$/, 'Enter a valid phone number')
167167
.optional(),
168168
officeAddress: z.string().max(200),
169+
areasOfInterest: z.preprocess(
170+
(val) =>
171+
typeof val === 'string'
172+
? val
173+
.split(',')
174+
.map((s) => s.trim())
175+
.filter(Boolean)
176+
: val,
177+
z.array(z.string()).default([])
178+
),
169179
});
170180

171181
export type FacultyProfileTopic = keyof typeof facultyProfileSchemas;

server/actions/faculty-profile.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ export async function editFacultyProfilePersonalDetails(
220220
linkedInId: validated.linkedInId,
221221
googleScholarId: validated.googleScholarId,
222222
researchGateId: validated.researchGateId,
223+
areasOfInterest: validated.areasOfInterest,
223224
})
224225
.where(eq(faculty.id, session.person.id));
225226

0 commit comments

Comments
 (0)