Skip to content

Commit

Permalink
fixes remove resume bug
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhelp committed Dec 31, 2024
1 parent a7ef7ac commit b06e199
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 43 deletions.
37 changes: 19 additions & 18 deletions apps/web/src/actions/user-profile-mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { decodeBase64AsFile } from "@/lib/utils/shared/files";
import { revalidatePath } from "next/cache";
import { getUser, getUserByTag } from "db/functions";
import { RegistrationSettingsFormValidator } from "@/validators/shared/RegistrationSettingsForm";
import { UNIQUE_KEY_CONSTRAINT_VIOLATION_CODE } from "@/lib/constants";
import c from "config";
import { DatabaseError } from "db/types";


export const modifyRegistrationData = authenticatedAction
.schema(RegistrationSettingsFormValidator)
Expand Down Expand Up @@ -41,6 +44,7 @@ export const modifyRegistrationData = authenticatedAction
},
ctx: { userId },
}) => {

await Promise.all([
// attempts to update both tables with Promise.all
db
Expand Down Expand Up @@ -75,6 +79,7 @@ export const modifyRegistrationData = authenticatedAction
})
.where(eq(userHackerData.clerkID, userId)),
]).catch(async (err) => {
console.log(`Error occured at modify registration data: ${err}`);
// If there's an error
return {
success: false,
Expand Down Expand Up @@ -114,7 +119,6 @@ export const deleteResume = authenticatedAction
}),
)
.action(async ({ parsedInput: { oldFileLink } }) => {
console.log(oldFileLink);
if (oldFileLink === c.noResumeProvidedURL) return null;
await del(oldFileLink);
});
Expand All @@ -133,14 +137,10 @@ export const modifyProfileData = authenticatedAction
parsedInput: { bio, discord, pronouns, skills },
ctx: { userId },
}) => {
const user = await getUser(userId);
if (!user) {
throw new Error("User not found");
}
await db
.update(userCommonData)
.set({ pronouns, bio, skills, discord })
.where(eq(userCommonData.clerkID, user.clerkID));
.where(eq(userCommonData.clerkID, userId));
return {
success: true,
newPronouns: pronouns,
Expand Down Expand Up @@ -171,18 +171,9 @@ export const modifyAccountSettings = authenticatedAction
},
ctx: { userId },
}) => {
const user = await getUser(userId);
if (!user) throw new Error("User not found");
let oldHackerTag = user.hackerTag; // change when hackertag is not PK on profileData table
if (oldHackerTag != hackerTag)
if (await getUserByTag(hackerTag))
//if hackertag changed
// copied from /api/registration/create
return {
success: false,
message: "hackertag_not_unique",
};
await db

try{
await db
.update(userCommonData)
.set({
firstName,
Expand All @@ -191,6 +182,16 @@ export const modifyAccountSettings = authenticatedAction
isSearchable: hasSearchableProfile,
})
.where(eq(userCommonData.clerkID, userId));
}
catch(err){
if (err instanceof DatabaseError && err.code === UNIQUE_KEY_CONSTRAINT_VIOLATION_CODE) {
return {
success: false,
message: "hackertag_not_unique",
};
}
throw err;
}
return {
success: true,
newFirstName: firstName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,29 @@ interface RegistrationFormSettingsProps {

export default function RegisterFormSettings({
user,
data,
data: originalData,
}: RegistrationFormSettingsProps) {
const form = useForm<z.infer<typeof RegistrationSettingsFormValidator>>({
resolver: zodResolver(RegistrationSettingsFormValidator),
defaultValues: {
hackathonsAttended: data.hackathonsAttended,
hackathonsAttended: originalData.hackathonsAttended,
dietaryRestrictions: user.dietRestrictions as any,
isEmailable: data.isEmailable,
isEmailable: originalData.isEmailable,
accommodationNote: user.accommodationNote || "",
age: user.age,
ethnicity: user.ethnicity as any,
gender: user.gender as any,
major: data.major,
github: data.GitHub ?? "",
heardAboutEvent: data.heardFrom as any,
levelOfStudy: data.levelOfStudy as any,
linkedin: data.LinkedIn ?? "",
personalWebsite: data.PersonalWebsite ?? "",
major: originalData.major,
github: originalData.GitHub ?? "",
heardAboutEvent: originalData.heardFrom as any,
levelOfStudy: originalData.levelOfStudy as any,
linkedin: originalData.LinkedIn ?? "",
personalWebsite: originalData.PersonalWebsite ?? "",
race: user.race as any,
shirtSize: user.shirtSize as any,
schoolID: data.schoolID,
softwareBuildingExperience: data.softwareExperience as any,
university: data.university,
schoolID: originalData.schoolID,
softwareBuildingExperience: originalData.softwareExperience as any,
university: originalData.university,
phoneNumber: user.phoneNumber,
countryOfResidence: user.countryOfResidence,
},
Expand All @@ -92,8 +92,8 @@ export default function RegisterFormSettings({
const { isSubmitSuccessful, isSubmitted, errors } = form.formState;
const hasErrors = !isSubmitSuccessful && isSubmitted;
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
let oldResumeLink: string = data.resume ?? c.noResumeProvidedURL;
let f = new File([data.resume], oldResumeLink.split("/").pop()!);
let oldResumeLink: string = originalData.resume ?? c.noResumeProvidedURL;
let f = new File([originalData.resume], oldResumeLink.split("/").pop()!);
useEffect(() => {
if (oldResumeLink === c.noResumeProvidedURL) setUploadedFile(null);
else setUploadedFile(f);
Expand All @@ -111,7 +111,7 @@ export default function RegisterFormSettings({
if (shortID === "NOT_LOCAL_SCHOOL") {
form.setValue("schoolID", "");
} else {
form.setValue("schoolID", data.schoolID);
form.setValue("schoolID", originalData.schoolID);
}
}
}, [universityValue]);
Expand All @@ -131,8 +131,8 @@ export default function RegisterFormSettings({
);
newResumeLink = newBlob.url;
}

const res = runModifyRegistrationData({
const oldResume = originalData.resume;
runModifyRegistrationData({
age: data.age,
gender: data.gender,
race: data.race,
Expand All @@ -156,7 +156,7 @@ export default function RegisterFormSettings({
uploadedFile: newResumeLink,
});

runDeleteResume({ oldFileLink: oldResumeLink });
runDeleteResume({ oldFileLink: oldResume });
}

const { execute: runModifyRegistrationData, status: loadingState } =
Expand All @@ -175,7 +175,6 @@ export default function RegisterFormSettings({
);
},
});

const { execute: runDeleteResume } = useAction(deleteResume);

const onDrop = useCallback(
Expand All @@ -186,10 +185,6 @@ export default function RegisterFormSettings({
);
}
if (acceptedFiles.length > 0) {
console.log(
`Got accepted file! The length of the array is ${acceptedFiles.length}.`,
);
console.log(acceptedFiles[0]);
setUploadedFile(acceptedFiles[0]);
setOldFile(false);
}
Expand All @@ -210,8 +205,7 @@ export default function RegisterFormSettings({
<Form {...form}>
<form
className="space-y-6"
onSubmit={form.handleSubmit(onSubmit)}
>
onSubmit={form.handleSubmit(onSubmit)}>
<FormGroupWrapper title="General">
<div className="grid grid-cols-1 gap-x-2 gap-y-2 md:grid-cols-7">
<FormField
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/lib/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const ONE_HOUR_IN_MILLISECONDS = 3600000;
export const FIVE_MINUTES_IN_MILLISECONDS = 300000;
export const VERCEL_IP_TIMEZONE_HEADER_KEY = "x-vercel-ip-timezone";
export const UNIQUE_KEY_CONSTRAINT_VIOLATION_CODE = "23505";
79 changes: 79 additions & 0 deletions packages/db/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,82 @@ export interface Hacker extends User {
team?: Team | null;
};
}
export interface NoticeOrError {
message: string | undefined;
severity: string | undefined;
code: string | undefined;
detail: string | undefined;
hint: string | undefined;
position: string | undefined;
internalPosition: string | undefined;
internalQuery: string | undefined;
where: string | undefined;
schema: string | undefined;
table: string | undefined;
column: string | undefined;
dataType: string | undefined;
constraint: string | undefined;
file: string | undefined;
line: string | undefined;
routine: string | undefined;
}
export type MessageName =
| "parseComplete"
| "bindComplete"
| "closeComplete"
| "noData"
| "portalSuspended"
| "replicationStart"
| "emptyQuery"
| "copyDone"
| "copyData"
| "rowDescription"
| "parameterDescription"
| "parameterStatus"
| "backendKeyData"
| "notification"
| "readyForQuery"
| "commandComplete"
| "dataRow"
| "copyInResponse"
| "copyOutResponse"
| "authenticationOk"
| "authenticationMD5Password"
| "authenticationCleartextPassword"
| "authenticationSASL"
| "authenticationSASLContinue"
| "authenticationSASLFinal"
| "error"
| "notice";

export class DatabaseError extends Error implements NoticeOrError {
public severity: string | undefined;
public code: string | undefined;
public detail: string | undefined;
public hint: string | undefined;
public position: string | undefined;
public internalPosition: string | undefined;
public internalQuery: string | undefined;
public where: string | undefined;
public schema: string | undefined;
public table: string | undefined;
public column: string | undefined;
public dataType: string | undefined;
public constraint: string | undefined;
public file: string | undefined;
public line: string | undefined;
public routine: string | undefined;
constructor(
message: string,
public readonly length: number,
public readonly name: MessageName,
) {
super(message);
}
// This is a work around as the true DatabaeError class is not properly exported in Vercel Postgres.
// Therefore, we create a mock up of the DatabaseError object sourced from: https://github.com/brianc/node-postgres/blob/8b2768f91d284ff6b97070aaf6602560addac852/packages/pg-protocol/src/messages.ts#L97
// And override the instance function as it is technically not the true class object
static [Symbol.hasInstance](instance: any) {
return instance.constructor.name === "DatabaseError";
}
}

0 comments on commit b06e199

Please sign in to comment.