fix
Desc: - Perubahan minor pada tampilan - Penambahan function
This commit is contained in:
@@ -12,9 +12,9 @@ import { useRouter } from "next/navigation";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-simple-toasts";
|
import toast from "react-simple-toasts";
|
||||||
import { gs_profile } from "../state/global_state";
|
import { gs_profile } from "../state/global_state";
|
||||||
import { g_getProfile } from "../fun/fun-get-profile";
|
import { g_getProfile } from "../fun/fun_get_profile";
|
||||||
|
|
||||||
export default function EditProfile({ data }: { data: any }) {
|
export default function EditProfile() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
//Get data profile
|
//Get data profile
|
||||||
@@ -24,6 +24,8 @@ export default function EditProfile({ data }: { data: any }) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function onUpdate() {
|
async function onUpdate() {
|
||||||
const body = profile;
|
const body = profile;
|
||||||
if (_.values(body).includes("")) return toast("Lengkapi data");
|
if (_.values(body).includes("")) return toast("Lengkapi data");
|
||||||
@@ -51,8 +53,8 @@ export default function EditProfile({ data }: { data: any }) {
|
|||||||
<>
|
<>
|
||||||
{/* {JSON.stringify(profile)} */}
|
{/* {JSON.stringify(profile)} */}
|
||||||
<Stack px={"sm"}>
|
<Stack px={"sm"}>
|
||||||
<TextInput label="Username" disabled value={data.User.username} />
|
<TextInput label="Username" disabled value={profile.User.username} />
|
||||||
<TextInput label="Nomor" disabled value={data.User.nomor} />
|
<TextInput label="Nomor" disabled value={profile.User.nomor} />
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
label="Nama"
|
label="Nama"
|
||||||
|
|||||||
@@ -24,13 +24,7 @@ export async function getProfile() {
|
|||||||
alamat: true,
|
alamat: true,
|
||||||
jenisKelamin: true,
|
jenisKelamin: true,
|
||||||
active: true,
|
active: true,
|
||||||
ImageProfile: {
|
imagesId: true,
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
url: true,
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
User: {
|
User: {
|
||||||
select : {
|
select : {
|
||||||
username: true,
|
username: true,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { myConsole } from "@/app/fun/my_console";
|
||||||
import { getProfile } from "..";
|
import { getProfile } from "..";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6,6 +7,9 @@ import { getProfile } from "..";
|
|||||||
* @returns data profile
|
* @returns data profile
|
||||||
*/
|
*/
|
||||||
export async function g_getProfile(setProfile: any) {
|
export async function g_getProfile(setProfile: any) {
|
||||||
const data = await getProfile().then((res) => res);
|
await getProfile()
|
||||||
setProfile(data)
|
.then((res) => res)
|
||||||
}
|
.then((val) => {
|
||||||
|
setProfile(val);
|
||||||
|
});
|
||||||
|
}
|
||||||
16
src/app_modules/katalog/profile/fun/get_foto_profile.ts
Normal file
16
src/app_modules/katalog/profile/fun/get_foto_profile.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
"use server";
|
||||||
|
import { myConsole } from "@/app/fun/my_console";
|
||||||
|
import prisma from "@/app/lib/prisma";
|
||||||
|
|
||||||
|
export async function getFotoProfile(id: any) {
|
||||||
|
const imgUrl = await prisma.images.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return imgUrl;
|
||||||
|
}
|
||||||
52
src/app_modules/katalog/profile/fun/upload_foto.ts
Normal file
52
src/app_modules/katalog/profile/fun/upload_foto.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { myConsole } from "@/app/fun/my_console";
|
||||||
|
import prisma from "@/app/lib/prisma";
|
||||||
|
import fs from "fs";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param formData
|
||||||
|
* @returns upload gambar ke /public/img
|
||||||
|
*/
|
||||||
|
export async function funUploadFoto(formData: FormData, id: string) {
|
||||||
|
const file: any = formData.get("file");
|
||||||
|
const fName = file.name;
|
||||||
|
const fExt = _.lowerCase(file.name.split(".").pop());
|
||||||
|
const fRandomName = v4(fName) + "." + fExt;
|
||||||
|
|
||||||
|
myConsole(id);
|
||||||
|
myConsole(fExt);
|
||||||
|
|
||||||
|
const upload = await prisma.images.create({
|
||||||
|
data: {
|
||||||
|
url: fRandomName,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (upload) {
|
||||||
|
await prisma.profile.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
imagesId: upload.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const upFolder = Buffer.from(await file.arrayBuffer());
|
||||||
|
fs.writeFileSync(`./public/img/${upload.url}`, upFolder);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: upload,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,8 +1,17 @@
|
|||||||
import ProfileLayout from "./create/layout";
|
import ProfileLayout from "./create/layout";
|
||||||
import CreateProfile from "./create/view";
|
import CreateProfile from "./create/view";
|
||||||
import {getProfile} from "./fun/api-get-profile";
|
import { getProfile } from "./fun/api-get-profile";
|
||||||
import EditProfileLayout from './edit/layout';
|
import EditProfileLayout from "./edit/layout";
|
||||||
import EditProfileView from './edit/view'
|
import EditProfileView from "./edit/view";
|
||||||
|
import UploadFotoProfile from "./upload/view";
|
||||||
|
import UploadFotoProfileLayout from "./upload/layout";
|
||||||
|
|
||||||
|
export {
|
||||||
export {ProfileLayout, CreateProfile, getProfile, EditProfileView, EditProfileLayout}
|
ProfileLayout,
|
||||||
|
CreateProfile,
|
||||||
|
getProfile,
|
||||||
|
EditProfileView,
|
||||||
|
EditProfileLayout,
|
||||||
|
UploadFotoProfile,
|
||||||
|
UploadFotoProfileLayout,
|
||||||
|
};
|
||||||
|
|||||||
94
src/app_modules/katalog/profile/upload/layout.tsx
Normal file
94
src/app_modules/katalog/profile/upload/layout.tsx
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ActionIcon,
|
||||||
|
AppShell,
|
||||||
|
FileButton,
|
||||||
|
Flex,
|
||||||
|
Footer,
|
||||||
|
Group,
|
||||||
|
Header,
|
||||||
|
Text,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { IconArrowLeft, IconUpload } from "@tabler/icons-react";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import toast from "react-simple-toasts";
|
||||||
|
import { gs_profile } from "../state/global_state";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import { g_getProfile } from "../fun/fun_get_profile";
|
||||||
|
import { funUploadFoto } from "../fun/upload_foto";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
export default function UploadFotoProfileLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: any;
|
||||||
|
}) {
|
||||||
|
const router = useRouter()
|
||||||
|
const [profile, setProfile] = useAtom(gs_profile);
|
||||||
|
useShallowEffect(() => {
|
||||||
|
g_getProfile(setProfile);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AppShell
|
||||||
|
header={
|
||||||
|
<Header height={50} px={"sm"}>
|
||||||
|
<Group position="apart" h={50}>
|
||||||
|
<ActionIcon
|
||||||
|
variant="transparent"
|
||||||
|
onClick={() => router.push("/dev/katalog/view")}
|
||||||
|
>
|
||||||
|
<IconArrowLeft />
|
||||||
|
</ActionIcon>
|
||||||
|
<Text>Upload Foto Profile</Text>
|
||||||
|
<ActionIcon variant="transparent"></ActionIcon>
|
||||||
|
</Group>
|
||||||
|
</Header>
|
||||||
|
}
|
||||||
|
footer={
|
||||||
|
<Footer height={70}>
|
||||||
|
<Flex align={"center"} justify={"center"} h={70} gap={"xl"}>
|
||||||
|
<Flex align={"center"} justify={"center"} h={70}>
|
||||||
|
<Flex direction={"column"} align={"center"}>
|
||||||
|
<FileButton
|
||||||
|
onChange={async (files) => {
|
||||||
|
const id = profile?.id
|
||||||
|
|
||||||
|
if (!files) return toast("File Kosong");
|
||||||
|
const fd = new FormData();
|
||||||
|
fd.append("file", files);
|
||||||
|
|
||||||
|
const upFoto = await funUploadFoto(fd, id);
|
||||||
|
if (upFoto.success) {
|
||||||
|
toast("Upload berhasil");
|
||||||
|
router.push("/dev/katalog/view")
|
||||||
|
// loadDataProfile(valUser.id, setUser, setProfile);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
accept="image/png,image/jpeg,image/webp"
|
||||||
|
>
|
||||||
|
{(props) => (
|
||||||
|
<ActionIcon {...props}>
|
||||||
|
<IconUpload />
|
||||||
|
</ActionIcon>
|
||||||
|
)}
|
||||||
|
</FileButton>
|
||||||
|
<Text fz={"sm"} fw={"bold"}>
|
||||||
|
Upload
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* */}
|
||||||
|
</Footer>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
{/* {JSON.stringify(profile)} */}
|
||||||
|
</AppShell>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
39
src/app_modules/katalog/profile/upload/view.tsx
Normal file
39
src/app_modules/katalog/profile/upload/view.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { AspectRatio, FileButton, Image, Paper, Title } from "@mantine/core";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { g_getProfile } from "../fun/fun_get_profile";
|
||||||
|
import { gs_profile } from "../state/global_state";
|
||||||
|
import { getFotoProfile } from "../fun/get_foto_profile";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ApiHipmi } from "@/app/lib/api";
|
||||||
|
import { myConsole } from "@/app/fun/my_console";
|
||||||
|
|
||||||
|
export default function UploadFotoProfile() {
|
||||||
|
const [profile, setProfile] = useAtom(gs_profile);
|
||||||
|
useShallowEffect(() => {
|
||||||
|
g_getProfile(setProfile);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [foto, setFoto] = useState<any | null>(null);
|
||||||
|
useShallowEffect(() => {
|
||||||
|
if (profile?.imagesId === undefined || profile?.imagesId === null) {
|
||||||
|
myConsole("Waiting data");
|
||||||
|
} else {
|
||||||
|
getFotoProfile(profile?.imagesId).then((res) => setFoto(res?.url));
|
||||||
|
}
|
||||||
|
}, [profile?.imagesId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* {JSON.stringify(foto)} */}
|
||||||
|
<AspectRatio ratio={1 / 1} >
|
||||||
|
<Paper p={"lg"}>
|
||||||
|
{foto ? <Image alt="" src={ApiHipmi.get_foto + `${foto}`} /> : <Image alt="" src={"/aset/avatar.png"} />}
|
||||||
|
</Paper>
|
||||||
|
</AspectRatio>
|
||||||
|
{/* {JSON.stringify(profile)} */}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -29,7 +29,9 @@ import { getProfile } from "../profile";
|
|||||||
import { gs_profile } from "../profile/state/global_state";
|
import { gs_profile } from "../profile/state/global_state";
|
||||||
import { myConsole } from "@/app/fun/my_console";
|
import { myConsole } from "@/app/fun/my_console";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { g_getProfile } from "../profile/fun/fun-get-profile";
|
import { g_getProfile } from "../profile/fun/fun_get_profile";
|
||||||
|
import { getFotoProfile } from "../profile/fun/get_foto_profile";
|
||||||
|
import { ApiHipmi } from "@/app/lib/api";
|
||||||
|
|
||||||
export default function KatalogView() {
|
export default function KatalogView() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -40,20 +42,51 @@ export default function KatalogView() {
|
|||||||
g_getProfile(setProfile);
|
g_getProfile(setProfile);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const [foto, setFoto] = useState<any | null>(null);
|
||||||
|
useShallowEffect(() => {
|
||||||
|
if (profile?.imagesId === undefined || profile?.imagesId === null) {
|
||||||
|
myConsole("Waiting data");
|
||||||
|
} else {
|
||||||
|
getFotoProfile(profile?.imagesId).then((res) => setFoto(res?.url));
|
||||||
|
}
|
||||||
|
myConsole(profile?.imagesId);
|
||||||
|
}, [profile?.imagesId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{/* Background dan foto */}
|
||||||
<Box>
|
<Box>
|
||||||
<Paper bg={"gray"} p={"md"}>
|
<Paper bg={"gray"} p={"md"}>
|
||||||
<Image alt="" src={"/aset/logo.png"} />
|
<Image alt="" src={"/aset/logo.png"} />
|
||||||
</Paper>
|
</Paper>
|
||||||
<Center>
|
<Center>
|
||||||
<Image
|
{foto ? (
|
||||||
alt=""
|
<Image
|
||||||
src={"/aset/avatar.png"}
|
radius={50}
|
||||||
height={100}
|
alt=""
|
||||||
width={100}
|
src={ApiHipmi.get_foto + `${foto}`}
|
||||||
sx={{ position: "absolute", marginBottom: 10, paddingBottom: 10 }}
|
height={100}
|
||||||
/>
|
width={100}
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
marginBottom: 10,
|
||||||
|
paddingBottom: 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Image
|
||||||
|
radius={50}
|
||||||
|
alt=""
|
||||||
|
src={"/aset/avatar.png"}
|
||||||
|
height={100}
|
||||||
|
width={100}
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
marginBottom: 10,
|
||||||
|
paddingBottom: 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Center>
|
</Center>
|
||||||
<Center>
|
<Center>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
@@ -62,7 +95,7 @@ export default function KatalogView() {
|
|||||||
variant="transparent"
|
variant="transparent"
|
||||||
bg={"gray"}
|
bg={"gray"}
|
||||||
radius={50}
|
radius={50}
|
||||||
// onClick={() => router.push("/dev/katalog/profile/upload")}
|
onClick={() => router.push("/dev/katalog/profile/upload")}
|
||||||
sx={{ position: "relative" }}
|
sx={{ position: "relative" }}
|
||||||
>
|
>
|
||||||
<IconCamera color="black" size={20} />
|
<IconCamera color="black" size={20} />
|
||||||
@@ -70,6 +103,7 @@ export default function KatalogView() {
|
|||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Username dan Nama */}
|
||||||
<Group position="apart">
|
<Group position="apart">
|
||||||
<Flex direction={"column"} mt={"lg"}>
|
<Flex direction={"column"} mt={"lg"}>
|
||||||
<Text fz={"lg"} fw={"bold"}>
|
<Text fz={"lg"} fw={"bold"}>
|
||||||
@@ -87,6 +121,7 @@ export default function KatalogView() {
|
|||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
|
{/* Info user: nomor, email dll */}
|
||||||
<Flex direction={"column"} pt={"lg"}>
|
<Flex direction={"column"} pt={"lg"}>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={"content"}>
|
<Grid.Col span={"content"}>
|
||||||
|
|||||||
Reference in New Issue
Block a user