feat: enhance user profile update functionality and error handling
- Added detailed error messages for various HTTP status codes in useUpdateProfile hook. - Refactored updateProfile service to handle full_name as separate first and last name fields. - Updated UpdateProfilePayload type to allow profile_picture to be a string or File. - Introduced resolveFileUrl utility function for consistent file URL resolution. - Improved loading and error state management in useUpdateProfile hook. - Added DEFAULT_AVATAR constant for default user avatar.
This commit is contained in:
@@ -3,7 +3,7 @@ import QRCode from "qrcode";
|
||||
|
||||
export function resolveImageUrl(path: string): string {
|
||||
if (!path) return "";
|
||||
if (path.startsWith("data:")) return path; // untuk QR data URL
|
||||
if (path.startsWith("data:")) return path;
|
||||
if (path.startsWith("http://") || path.startsWith("https://")) {
|
||||
return path;
|
||||
}
|
||||
@@ -12,7 +12,6 @@ export function resolveImageUrl(path: string): string {
|
||||
return `${origin}${path.startsWith("/") ? "" : "/"}${path}`;
|
||||
}
|
||||
|
||||
// Load Image dari URL
|
||||
export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
@@ -23,9 +22,7 @@ export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||
});
|
||||
}
|
||||
|
||||
// Load kedua font dari Google Fonts (hanya sekali)
|
||||
export async function ensureFontsLoaded(): Promise<void> {
|
||||
// Trigger & tunggu font yang sudah diload via <link> di index.html
|
||||
await Promise.all([
|
||||
document.fonts.load('105px "Great Vibes"'),
|
||||
document.fonts.load('54px "Grenze"'),
|
||||
@@ -33,7 +30,6 @@ export async function ensureFontsLoaded(): Promise<void> {
|
||||
await document.fonts.ready;
|
||||
}
|
||||
|
||||
// Generate satu sertifikat sebagai Blob
|
||||
export async function generateCertificate(
|
||||
templateUrl: string,
|
||||
internName: string,
|
||||
@@ -42,7 +38,6 @@ export async function generateCertificate(
|
||||
ProjectDuration: string,
|
||||
verifyUrl: string,
|
||||
): Promise<Blob> {
|
||||
// Pastikan font siap sebelum menggambar teks
|
||||
await ensureFontsLoaded();
|
||||
|
||||
const img = await loadImage(templateUrl);
|
||||
@@ -84,17 +79,17 @@ export async function generateCertificate(
|
||||
ctx.fillStyle = "#090909";
|
||||
ctx.fillText(ProjectDuration, canvas.width * 0.68, canvas.height * 0.66);
|
||||
|
||||
// QR code — kalau verifyUrl diisi
|
||||
// QR code — nanti akan diganti ke alamat domain
|
||||
const qrDataUrl = await QRCode.toDataURL('http://localhost:5173/verify-certificate/' + verifyUrl, {
|
||||
width: 200,
|
||||
margin: 1,
|
||||
});
|
||||
const qrImg = await loadImage(qrDataUrl);
|
||||
const qrSize = canvas.width * 0.103;
|
||||
const qrSize = canvas.width;
|
||||
ctx.drawImage(
|
||||
qrImg,
|
||||
canvas.width * 0.8 - qrSize,
|
||||
canvas.height * 0.75 - qrSize,
|
||||
canvas.width * 0.855 - qrSize,
|
||||
canvas.height * 0.85 - qrSize,
|
||||
qrSize,
|
||||
qrSize,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user