Fix upload

Deksripsi:
- Fix upload foto
- Fix email regex
This commit is contained in:
2024-12-11 10:32:00 +08:00
parent b2e48ba06c
commit 6e1a2e4bd3
13 changed files with 376 additions and 219 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -40,6 +40,7 @@
"@tiptap/pm": "^2.2.3", "@tiptap/pm": "^2.2.3",
"@tiptap/react": "^2.2.3", "@tiptap/react": "^2.2.3",
"@tiptap/starter-kit": "^2.2.3", "@tiptap/starter-kit": "^2.2.3",
"@types/bun": "^1.1.14",
"@types/lodash": "^4.17.4", "@types/lodash": "^4.17.4",
"@types/mapbox-gl": "^3.4.0", "@types/mapbox-gl": "^3.4.0",
"@types/node": "20.4.5", "@types/node": "20.4.5",
@@ -48,6 +49,7 @@
"@types/uuid": "^9.0.4", "@types/uuid": "^9.0.4",
"autoprefixer": "10.4.14", "autoprefixer": "10.4.14",
"bufferutil": "^4.0.8", "bufferutil": "^4.0.8",
"bun": "^1.1.38",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"echarts": "^5.4.3", "echarts": "^5.4.3",

View File

@@ -12,6 +12,7 @@ export async function POST(req: Request) {
}, },
}); });
try {
if (cekUsername) if (cekUsername)
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Username sudah digunakan" }, { success: false, message: "Username sudah digunakan" },
@@ -32,27 +33,13 @@ export async function POST(req: Request) {
user: createUser as any, user: createUser as any,
}); });
// try {
// const createUserSession = await prisma.userSession.create({
// data: {
// token: token as string,
// userId: createUser.id,
// },
// });
// if (!createUserSession)
// return NextResponse.json(
// { success: false, message: "Gagal Membuat Session" },
// { status: 400 }
// );
// } catch (error) {
// console.log(error);
// }
return NextResponse.json( return NextResponse.json(
{ success: true, message: "Berhasil Login", data: createUser }, { success: true, message: "Berhasil Login", data: createUser },
{ status: 200 } { status: 200 }
); );
} catch (error) {
console.log(error);
}
} }
return NextResponse.json( return NextResponse.json(

View File

@@ -20,7 +20,7 @@ export async function POST(req: Request) {
}, },
}); });
if (dataUser === null) if (dataUser == null)
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Nomor Belum Terdaftar" }, { success: false, message: "Nomor Belum Terdaftar" },
{ status: 404 } { status: 404 }
@@ -32,37 +32,6 @@ export async function POST(req: Request) {
user: dataUser as any, user: dataUser as any,
}); });
// const cekSessionUser = await prisma.userSession.findFirst({
// where: {
// userId: dataUser.id,
// },
// });
// if (cekSessionUser !== null) {
// await prisma.userSession.delete({
// where: {
// userId: dataUser.id,
// },
// });
// }
// try {
// const createUserSession = await prisma.userSession.create({
// data: {
// token: token as string,
// userId: dataUser.id,
// },
// });
// if (!createUserSession)
// return NextResponse.json(
// { success: false, message: "Gagal Membuat Session" },
// { status: 400 }
// );
// } catch (error) {
// console.log(error);
// }
return NextResponse.json( return NextResponse.json(
{ {
success: true, success: true,

View File

@@ -0,0 +1,51 @@
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const WS_APIKEY = process.env.WS_APIKEY;
console.log(WS_APIKEY);
try {
const formData = await request.formData();
const res = await fetch("https://wibu-storage.wibudev.com/api/upload", {
method: "POST",
body: formData,
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},
});
// if (res.ok) {
// console.log("Berhasil");
// const hasil = await res.json();
// return { success: true, data: hasil.data };
// } else {
// const errorText = await res.text();
// return { success: false, data: {} };
// }
} catch (error) {
console.log(error);
}
// try {
// const res = await fetch("https://wibu-storage.wibudev.com/api/upload", {
// method: "POST",
// body: formData,
// headers: {
// Authorization: `Bearer ${process.env.WS_APIKEY}`,
// },
// });
// if (res.ok) {
// const hasil = await res.json();
// return { success: true, data: hasil.data };
// } else {
// const errorText = await res.text();
// return { success: false, data: {} };
// }
// } catch (error) {
// console.error("Upload error:", error);
// return { success: false, data: {} };
// }
return NextResponse.json({ success: true });
}

View File

@@ -1,18 +1,111 @@
"use client";
import { MainColor } from "@/app_modules/_global/color";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import Coba_TestLoading from "@/app_modules/zCoba"; import Coba_TestLoading from "@/app_modules/zCoba";
import {
Avatar,
Button,
Center,
FileButton,
Paper,
Stack,
} from "@mantine/core";
import { IconCamera } from "@tabler/icons-react";
import { useState } from "react";
import { DIRECTORY_ID } from "../lib";
import { TokenStorage } from "../lib/token";
import { envs } from "@/lib/envs";
export default async function Page() { export default function Page() {
await new Promise((a, b) => { const [filePP, setFilePP] = useState<File | null>(null);
setTimeout(a, 3000); const [imgPP, setImgPP] = useState<any | null>();
async function onSave() {
const body = {
file: filePP,
dirId: DIRECTORY_ID.profile_foto,
};
const token =
"QWERTYUIOPLKJHGFDSAZXCVBNMQAZWSXEDCRFVTGBYHNUJMIKOLPPOIUYTREWQLKJHGFDSAMNBVCXZlghvftyguhijknhbgvcfytguu8okjnhbgvfty7u8oilkjnhgvtygu7u8ojilnkhbgvhujnkhghvjhukjnhb";
const formData = new FormData();
formData.append("file", filePP as any);
const res = await fetch("/api/upload", {
method: "POST",
body: formData,
}); });
const userLoginId = await funGetUserIdByToken(); console.log(await res.json());
}
return ( return (
<> <>
{/* <CobaRealtime userLoginId={userLoginId} /> */} <Stack>
<Coba_TestLoading userLoginId={userLoginId as string} /> <Center>
{/* <ComponentGlobal_UI_LayoutTamplate /> */} {imgPP ? (
<Paper shadow="lg" radius={"100%"}>
<Avatar
color={"cyan"}
sx={{
borderStyle: "solid",
borderColor: "gray",
borderWidth: "0.5px",
}}
src={imgPP ? imgPP : "/aset/global/avatar.png"}
size={150}
radius={"100%"}
/>
</Paper>
) : (
<Paper shadow="lg" radius={"100%"}>
<Avatar
variant="light"
color="blue"
size={150}
radius={"100%"}
sx={{
borderStyle: "solid",
borderColor: MainColor.darkblue,
borderWidth: "0.5px",
}}
/>
</Paper>
)}
</Center>
<FileButton
onChange={async (files: any | null) => {
try {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
setImgPP(buffer);
setFilePP(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
leftIcon={<IconCamera />}
bg={MainColor.yellow}
color="yellow"
c={"black"}
>
Upload
</Button>
)}
</FileButton>
<Button onClick={() => onSave()}>Upload</Button>
</Stack>
</> </>
); );
} }

View File

@@ -54,6 +54,4 @@ export async function funGlobal_UploadToStorage({
console.error("Error:", error); console.error("Error:", error);
return { success: false, data: {} }; return { success: false, data: {} };
} }
return { success: false, data: { id: "" } };
} }

View File

@@ -64,6 +64,11 @@ export default function Register() {
const result = await res.json(); const result = await res.json();
if (res.status === 400) {
setLoading(false);
ComponentGlobal_NotifikasiPeringatan(result.message);
}
if (res.status === 200) { if (res.status === 200) {
localStorage.removeItem("hipmi_auth_code_id"); localStorage.removeItem("hipmi_auth_code_id");
ComponentGlobal_NotifikasiBerhasil(result.message); ComponentGlobal_NotifikasiBerhasil(result.message);
@@ -73,11 +78,6 @@ export default function Register() {
nomor: data.nomor, nomor: data.nomor,
}); });
} }
if (res.status === 400) {
setLoading(false);
ComponentGlobal_NotifikasiPeringatan(result.message);
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@@ -1,15 +1,48 @@
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin"; import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
import { RouterPortofolio, RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import {
RouterPortofolio,
RouterProfile,
} from "@/app/lib/router_hipmi/router_katalog";
import { AccentColor } from "@/app_modules/_global/color"; import { AccentColor } from "@/app_modules/_global/color";
import {
gs_admin_navbar_menu,
gs_admin_navbar_subMenu,
} from "@/app_modules/admin/_admin_global/new_global_state";
import Component_ButtonLogout from "@/app_modules/auth/logout/view"; import Component_ButtonLogout from "@/app_modules/auth/logout/view";
import { ActionIcon, Drawer, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import {
ActionIcon,
Drawer,
Group,
SimpleGrid,
Stack,
Text,
} from "@mantine/core";
import { IconDashboard } from "@tabler/icons-react"; import { IconDashboard } from "@tabler/icons-react";
import { IconEdit, IconPencilPlus, IconPhotoEdit, IconPolaroid, IconX } from "@tabler/icons-react"; import {
IconEdit,
IconPencilPlus,
IconPhotoEdit,
IconPolaroid,
IconX,
} from "@tabler/icons-react";
import { useAtom } from "jotai";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
export default function DrawerKatalogNew({ opened, close, userRoleId, userId }: { opened: boolean, close: () => void, userRoleId: string, userId: string }) { export default function DrawerKatalogNew({
const param = useParams<{ id: string }>() opened,
const router = useRouter() close,
userRoleId,
userId,
}: {
opened: boolean;
close: () => void;
userRoleId: string;
userId: string;
}) {
const param = useParams<{ id: string }>();
const router = useRouter();
const [activeId, setActiveId] = useAtom(gs_admin_navbar_menu);
const [activeChildId, setActiveChildId] = useAtom(gs_admin_navbar_subMenu);
const listPage = [ const listPage = [
{ {
@@ -38,7 +71,8 @@ export default function DrawerKatalogNew({ opened, close, userRoleId, userId }:
}, },
]; ];
return <> return (
<>
<Drawer <Drawer
opened={opened} opened={opened}
onClose={() => close()} onClose={() => close()}
@@ -78,7 +112,9 @@ export default function DrawerKatalogNew({ opened, close, userRoleId, userId }:
<ActionIcon <ActionIcon
variant="transparent" variant="transparent"
c="white" c="white"
onClick={() => { router.push(e.path, { scroll: false }); }} onClick={() => {
router.push(e.path, { scroll: false });
}}
> >
{e.icon} {e.icon}
</ActionIcon> </ActionIcon>
@@ -94,7 +130,13 @@ export default function DrawerKatalogNew({ opened, close, userRoleId, userId }:
<ActionIcon <ActionIcon
variant="transparent" variant="transparent"
c="white" c="white"
onClick={() => { router.push(RouterAdminDashboard.main_admin, { scroll: false }); }} onClick={() => {
setActiveId("Main");
setActiveChildId("");
router.push(RouterAdminDashboard.main_admin, {
scroll: false,
});
}}
> >
<IconDashboard /> <IconDashboard />
</ActionIcon> </ActionIcon>
@@ -106,5 +148,6 @@ export default function DrawerKatalogNew({ opened, close, userRoleId, userId }:
</SimpleGrid> </SimpleGrid>
</Stack> </Stack>
</Drawer> </Drawer>
</>; </>
);
} }

View File

@@ -1,2 +1,3 @@
export var validRegex = export var validRegex =
/^([a-zA-Z0-9\.!#$%&'*+/=?^_`{|}~-]+)@([a-zA-Z0-9])+.([a-z]+)(.[a-z]+)?$/; /^([a-zA-Z0-9\.!#$%&'*+/=?^_`{|}~-]+)@([a-zA-Z0-9])+.([a-z]+)(.[a-z]+)?$/;
export const gmailRegex = /^[a-zA-Z0-9._%+-]+@gmail\.com$/;

View File

@@ -16,6 +16,8 @@ import { useState } from "react";
import funCreateNewProfile from "../../fun/fun_create_profile"; import funCreateNewProfile from "../../fun/fun_create_profile";
import { MODEL_PROFILE } from "../../model/interface"; import { MODEL_PROFILE } from "../../model/interface";
import { validRegex } from "@/app_modules/katalog/component"; import { validRegex } from "@/app_modules/katalog/component";
import { envs } from "@/lib/envs";
import { TokenProvider, TokenStorage } from "@/app/lib/token";
export function Profile_ComponentCreateNewProfile({ export function Profile_ComponentCreateNewProfile({
value, value,
@@ -54,7 +56,6 @@ export function Profile_ComponentCreateNewProfile({
file: filePP, file: filePP,
dirId: DIRECTORY_ID.profile_foto, dirId: DIRECTORY_ID.profile_foto,
}); });
// console.log("ini foto", uploadPhoto);
if (!uploadPhoto.success) { if (!uploadPhoto.success) {
setLoading(false); setLoading(false);
return ComponentGlobal_NotifikasiPeringatan( return ComponentGlobal_NotifikasiPeringatan(
@@ -62,12 +63,10 @@ export function Profile_ComponentCreateNewProfile({
); );
} }
if (uploadPhoto.success) {
const uploadBackground = await funGlobal_UploadToStorage({ const uploadBackground = await funGlobal_UploadToStorage({
file: fileBG, file: fileBG,
dirId: DIRECTORY_ID.profile_background, dirId: DIRECTORY_ID.profile_background,
}); });
// console.log("ini background", uploadBackground);
if (!uploadBackground.success) { if (!uploadBackground.success) {
setLoading(false); setLoading(false);
return ComponentGlobal_NotifikasiPeringatan( return ComponentGlobal_NotifikasiPeringatan(
@@ -75,24 +74,18 @@ export function Profile_ComponentCreateNewProfile({
); );
} }
if (uploadBackground.success) {
const create = await funCreateNewProfile({ const create = await funCreateNewProfile({
data: newData as any, data: newData as any,
imageId: uploadPhoto.data.id, imageId: uploadPhoto.data.id,
imageBackgroundId: uploadBackground.data.id, imageBackgroundId: uploadBackground.data.id,
}); });
if (create.status === 201) { if (create.status === 201) {
ComponentGlobal_NotifikasiBerhasil( ComponentGlobal_NotifikasiBerhasil("Berhasil membuat profile", 3000);
"Berhasil membuat profile",
3000
);
router.push(RouterHome.main_home, { scroll: false }); router.push(RouterHome.main_home, { scroll: false });
} else { } else {
ComponentGlobal_NotifikasiGagal(create.message); ComponentGlobal_NotifikasiGagal(create.message);
setLoading(false); setLoading(false);
} }
}
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@@ -24,6 +24,8 @@ import { IconAt, IconCamera, IconUpload } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
import { validRegex } from "../../component"; import { validRegex } from "../../component";
import { Profile_ComponentCreateNewProfile } from "../_component"; import { Profile_ComponentCreateNewProfile } from "../_component";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
import { gmailRegex } from "../../component/regular_expressions";
export default function CreateProfile() { export default function CreateProfile() {
const [filePP, setFilePP] = useState<File | null>(null); const [filePP, setFilePP] = useState<File | null>(null);
@@ -38,6 +40,9 @@ export default function CreateProfile() {
jenisKelamin: "", jenisKelamin: "",
}); });
// Maksimal ukuran file dalam byte (2 MB)
const MAX_SIZE = 2 * 1024 * 1024; // 2 MB
return ( return (
<> <>
<Stack px={"sm"} spacing={40}> <Stack px={"sm"} spacing={40}>
@@ -83,8 +88,15 @@ export default function CreateProfile() {
const buffer = URL.createObjectURL( const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())]) new Blob([new Uint8Array(await files.arrayBuffer())])
); );
if (files.size > MAX_SIZE) {
ComponentGlobal_NotifikasiPeringatan(
"Ukuran file terlalu besar. Maksimal 2 MB."
);
} else {
setImgPP(buffer); setImgPP(buffer);
setFilePP(files); setFilePP(files);
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@@ -138,8 +150,15 @@ export default function CreateProfile() {
const buffer = URL.createObjectURL( const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())]) new Blob([new Uint8Array(await files.arrayBuffer())])
); );
if (files.size > MAX_SIZE) {
ComponentGlobal_NotifikasiPeringatan(
"Ukuran file terlalu besar. Maksimal 2 MB."
);
} else {
setImgBG(buffer); setImgBG(buffer);
setFileBG(files); setFileBG(files);
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@@ -189,7 +208,7 @@ export default function CreateProfile() {
maxLength={100} maxLength={100}
placeholder="Contoh: User@gmail.com" placeholder="Contoh: User@gmail.com"
error={ error={
value.email.length > 0 && !value.email.match(validRegex) ? ( value.email.length > 0 && !value.email.match(gmailRegex) ? (
<ComponentGlobal_ErrorInput text="Invalid Email" /> <ComponentGlobal_ErrorInput text="Invalid Email" />
) : ( ) : (
"" ""

View File

@@ -19,6 +19,7 @@ const middlewareConfig: MiddlewareConfig = {
userPath: "/dev/home", userPath: "/dev/home",
publicRoutes: [ publicRoutes: [
"/", "/",
"/api/upload",
"/api/validation", "/api/validation",
"/api/auth/*", "/api/auth/*",
"/api/origin-url", "/api/origin-url",