diff --git a/prisma/migrations/20240411065853_new_user_fields/migration.sql b/prisma/migrations/20240411065853_new_user_fields/migration.sql new file mode 100644 index 00000000..b02cb31d --- /dev/null +++ b/prisma/migrations/20240411065853_new_user_fields/migration.sql @@ -0,0 +1,4 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "role" TEXT, +ADD COLUMN "title" TEXT, +ADD COLUMN "video" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a8387072..2b95e0d4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -43,6 +43,9 @@ model User { isEmailVerified Boolean @default(false) about String? picture String? + video String? + title String? + role String? counterStartDate Int @default(0) weeklyTransactionCounter Int @default(0) workerProfile WorkerProfile? @relation("WorkerProfile") diff --git a/src/app/api/delegate/service/route.ts b/src/app/api/delegate/service/route.ts index 30a35702..72cc8926 100644 --- a/src/app/api/delegate/service/route.ts +++ b/src/app/api/delegate/service/route.ts @@ -94,7 +94,14 @@ export async function POST(req: Request) { cid: cid, }); - console.log('Creating service with args', userId, platformId, cid, signature); + console.log( + 'Creating service with args', + userId, + platformId, + cid, + signature, + servicePostingFee, + ); transaction = await walletClient.writeContract({ address: config.contracts.serviceRegistry, diff --git a/src/app/api/users/[id]/route.ts b/src/app/api/users/[id]/route.ts index 7e610f1a..8be2d7d2 100644 --- a/src/app/api/users/[id]/route.ts +++ b/src/app/api/users/[id]/route.ts @@ -3,12 +3,23 @@ import prisma from '../../../../postgre/postgreClient'; import { logAndReturnApiError } from '../../../utils/handleApiErrors'; import { ERROR_UPDATING_USER } from '../../../../modules/BuilderPlace/apiResponses'; import { IEmailPreferences, IMutation } from '../../../../types'; +import { sendTransactionalEmailValidation } from '../../../../pages/api/utils/sendgrid'; export interface UsersFields { - // email?: string | null; - //TODO complete + name?: string; + email?: string; + about?: string; + picture?: string; + video?: string; + title?: string; + role?: string; + workerProfileFields?: WorkerProfileFields; emailPreferences?: IEmailPreferences | null; } + +interface WorkerProfileFields { + skills?: string[]; +} export interface IUpdateProfile extends IMutation {} /** @@ -37,15 +48,63 @@ export async function PUT(req: Request, { params }: { params: { id: string } }) try { console.log('Updating profile...', params.id); + + // Fetch current user data from the database + const currentUser = await prisma.user.findUnique({ + where: { id: Number(params.id) }, + }); + + if (!currentUser) { + return Response.json({ error: 'User not found' }, { status: 404 }); + } + + const { workerProfileFields, emailPreferences, ...userDataFields } = body.data; + + const isEmailUpdated = !!userDataFields.email && userDataFields.email !== currentUser.email; + + let updatedUserDataFields = { + ...userDataFields, + // Reset isEmailVerified if email is updated + ...(isEmailUpdated && { isEmailVerified: false }), + ...(!!emailPreferences && { emailPreferences }), + }; + + console.log('userDataFields', updatedUserDataFields); + console.log('isEmailUpdated', isEmailUpdated); + console.log('emailPreferences', emailPreferences); + console.log('userDataFields', userDataFields); + + // Update User data const user = await prisma.user.update({ where: { id: Number(params.id), }, data: { - emailPreferences: { ...body.data.emailPreferences }, + ...updatedUserDataFields, }, }); + // Update or create WorkerProfile if skills are provided + if (workerProfileFields?.skills) { + await prisma.workerProfile.upsert({ + where: { id: Number(params.id) }, + update: { skills: workerProfileFields.skills }, + create: { + id: Number(params.id), + skills: workerProfileFields.skills, + }, + }); + } + + // Send validation email if email is updated + if (isEmailUpdated) + await sendTransactionalEmailValidation( + user.email, + user.id.toString(), + user.name, + body?.domain, + ); + return Response.json({ id: user?.id }, { status: 200 }); } catch (e: any) { const error = logAndReturnApiError(e, ERROR_UPDATING_USER); diff --git a/src/components/Form/ProfileForm.tsx b/src/components/Form/ProfileForm.tsx index b8765312..e0c0ad2d 100644 --- a/src/components/Form/ProfileForm.tsx +++ b/src/components/Form/ProfileForm.tsx @@ -9,6 +9,8 @@ import { showErrorTransactionToast } from '../../utils/toast'; import Loading from '../Loading'; import SubmitButton from './SubmitButton'; import { SkillsInput } from './skills-input'; +import { CheckIcon, XMarkIcon } from '@heroicons/react/24/outline'; +import { createVerificationEmailToast } from '../../modules/BuilderPlace/utils/toast'; export interface IUpdateProfileFormValues { title?: string; @@ -18,6 +20,7 @@ export interface IUpdateProfileFormValues { name?: string; about?: string; skills?: string; + email?: string; } const validationSchema = Yup.object({ @@ -36,14 +39,17 @@ function ProfileForm({ callback }: { callback?: () => void }) { return ; } + const initialSkills = user?.workerProfile?.skills.toString() || userDescription?.skills_raw || ''; + const initialValues: IUpdateProfileFormValues = { - title: userDescription?.title || '', - role: userDescription?.role || '', - image_url: userDescription?.image_url || user?.picture || '', - video_url: userDescription?.video_url || '', - name: userDescription?.name || user?.name || '', - about: userDescription?.about || '', - skills: userDescription?.skills_raw || '', + title: user?.title || userDescription?.title || '', + role: user?.role || userDescription?.role || '', + image_url: user?.picture || userDescription?.image_url || user?.picture || '', + video_url: user?.video || userDescription?.video_url || '', + name: user?.name || userDescription?.name || user?.name || '', + about: user?.about || userDescription?.about || '', + skills: initialSkills, + email: user?.email || '', }; const onSubmit = async ( @@ -57,6 +63,10 @@ function ProfileForm({ callback }: { callback?: () => void }) { callback(); } + if (initialValues.email !== values.email) { + await createVerificationEmailToast(); + } + refreshData(); setSubmitting(false); } catch (error) { @@ -99,6 +109,7 @@ function ProfileForm({ callback }: { callback?: () => void }) { + + + +