Portofolio

#feat
- Create porto
- Edit Porto
- Upload gambar background profile
- List user
- Search user
## No issuue
This commit is contained in:
2024-01-19 14:16:16 +08:00
parent 01da30bdb5
commit 5f4337333a
175 changed files with 3451 additions and 1017 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function Admin_LayoutBuktiTransferInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Bukti Transfer" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Bukti Transfer" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -12,7 +12,7 @@ export default function Admin_LayoutHalamanAksi({
return (
<>
{/* {children} */}
<AppShell padding={"md"} header={<HeaderTamplate title="Pilih Aksi" />}>
<AppShell padding={"md"} header={<ComponentGlobal_HeaderTamplate title="Pilih Aksi" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function Admin_LayoutKonfirmasiInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Konfimasi Investasi" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Konfimasi Investasi" />}>
{children}
</AppShell>
</>

View File

@@ -2,13 +2,13 @@
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { RouterUserProfile } from "@/app/lib/router_hipmi/router_user_profile";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { Warna } from "@/app/lib/warna";
import funEditInvestasi from "@/app_modules/investasi/fun/fun_edit_investasi";
import funGantiStatusInvestasi from "@/app_modules/investasi/fun/fun_ganti_status";
import { gs_StatusPortoInvestasi } from "@/app_modules/investasi/g_state";
import { MODEL_Investasi } from "@/app_modules/investasi/model/model_investasi";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
import {
Group,
Flex,
@@ -64,7 +64,7 @@ export default function Admin_KonfirmasiInvestasi({
dataUser,
}: {
dataInvestasi: MODEL_Investasi;
dataUser: MODEL_User_profile;
dataUser: MODEL_PROFILE_OLD;
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
@@ -139,14 +139,14 @@ export default function Admin_KonfirmasiInvestasi({
<IconChevronLeft />
</ActionIcon>
<Flex align={"center"} gap={"xs"} pl={"lg"}>
<Avatar
{/* <Avatar
radius={50}
size={"md"}
src={
RouterUserProfile.api_foto +
RouterProfile.api_foto +
`${user.Profile?.ImageProfile?.url}`
}
/>
/> */}
<Text>{user.username}</Text>
</Flex>
</Group>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function Admin_LayoutStatusTransferInvesatasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Status Transfer" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Status Transfer" />}>
{children}
</AppShell>
</>

View File

@@ -20,7 +20,7 @@ import {
useMantineTheme,
} from "@mantine/core";
import React, { useState } from "react";
import HeaderTamplate from "../../component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "../../component_global/header_tamplate";
import { useDisclosure } from "@mantine/hooks";
import { IconLetterH, IconLogout } from "@tabler/icons-react";
import {

View File

@@ -3,6 +3,6 @@ import Login from "./login/view";
import Validasi from "./validasi/view";
import LayoutValidasi from "./validasi/layout";
import Register from "./register/view";
import Logout from "./logout/view";
import User_Logout from "./logout/view";
export { SplashScreen, Login, Validasi, Register, Logout, LayoutValidasi };
export { SplashScreen, Login, Validasi, Register, User_Logout as Logout, LayoutValidasi };

View File

@@ -1,33 +1,28 @@
"use client";
import { myConsole } from "@/app/fun/my_console";
import { ApiHipmi } from "@/app/lib/api";
import { ActionIcon, Button, Group, Modal } from "@mantine/core";
import { ActionIcon, Button, Group, Modal, Stack, Title } from "@mantine/core";
import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { gs_nomor, gs_otp } from "../state/state";
import { IconLogout } from "@tabler/icons-react";
import { Warna } from "@/app/lib/warna";
import { gs_token } from "@/app_modules/home/state/global_state";
import { useDisclosure } from "@mantine/hooks";
export default function Logout() {
export default function User_Logout() {
const router = useRouter();
const [nomor, setnomor] = useAtom(gs_nomor);
const [code, setCode] = useAtom(gs_otp);
const [token, setToken] = useAtom(gs_token);
const [opened, { toggle }] = useDisclosure(false);
const onLogout = async () => {
// MyConsole("keluar");
await fetch(ApiHipmi.logout)
.then((res) => res.json())
.then((val) => {
if (val.status == 200) {
setnomor(null);
setCode(null);
setToken(null);
return router.push("/dev/auth/login");
}
@@ -36,25 +31,31 @@ export default function Logout() {
return (
<>
<Modal opened={opened} onClose={toggle} centered title="Yakin ingin keluar ?">
<Group align="center" position="center">
<Button compact onClick={toggle} radius={50}>
Batal
</Button>
<Button
compact
radius={50}
bg={Warna.merah}
color="red"
onClick={() => onLogout()}
>
Keluar
</Button>
</Group>
<Modal opened={opened} onClose={toggle} centered withCloseButton={false}>
<Stack>
<Title order={6}>Anda yakin ingin keluar ?</Title>
<Group align="center" position="center">
<Button compact onClick={toggle} radius={50}>
Batal
</Button>
<Button
compact
radius={50}
bg={Warna.merah}
color="red"
onClick={() => onLogout()}
>
Keluar
</Button>
</Group>
</Stack>
</Modal>
<ActionIcon variant="transparent">
{/* <ActionIcon variant="transparent">
<IconLogout color={Warna.merah} onClick={toggle} />
</ActionIcon>
</ActionIcon> */}
<Button radius={"xl"} color={"red"} onClick={toggle}>
Logout
</Button>
</>
);
}

View File

@@ -19,7 +19,7 @@ import { IconChevronLeft, IconCircleLetterH } from "@tabler/icons-react";
import toast from "react-simple-toasts";
import { ApiHipmi } from "@/app/lib/api";
import { useRouter } from "next/navigation";
import { funGetUserProfile } from "@/app_modules/fun/get_user_profile";
import { funGetUserProfile } from "@/app_modules/fun_global/get_user_profile";
import { useFocusTrap } from "@mantine/hooks";
import { NotifBerhasil } from "@/app_modules/donasi/component/notifikasi/notif_berhasil";
import { NotifGagal } from "@/app_modules/donasi/component/notifikasi/notif_gagal";

View File

@@ -1,10 +1,10 @@
"use client";
import { Header, Group, ActionIcon, Text } from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import { Header, Group, ActionIcon, Text, Title } from "@mantine/core";
import { IconArrowLeft, IconChevronLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
export default function HeaderTamplate({
export default function ComponentGlobal_HeaderTamplate({
route,
route2,
title,
@@ -18,7 +18,7 @@ export default function HeaderTamplate({
const router = useRouter();
return (
<>
<Header height={50}>
<Header height={50} sx={{ borderStyle: "none" }}>
<Group h={50} position="apart" px={"md"}>
<ActionIcon
variant="transparent"
@@ -30,11 +30,11 @@ export default function HeaderTamplate({
}
}}
>
<IconArrowLeft />
<IconChevronLeft />
</ActionIcon>
<Text>{title}</Text>
<Title order={5}>{title}</Title>
{(() => {
if (route2 === null ||route2 === undefined) {
if (route2 === null || route2 === undefined) {
return <ActionIcon disabled variant="transparent"></ActionIcon>;
} else {
return (

View File

@@ -0,0 +1,31 @@
import { Center, Text } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconAlertTriangle, IconChecklist, IconCircleCheck } from "@tabler/icons-react";
/**
*
* @param text | masukan text untuk peringatan
* @type string
* @returns notifikasi peringatan
*/
export async function ComponentGlobal_NotifikasiBerhasil(text: string) {
return notifications.show({
message: (
<Center>
<Text fw={"bold"}>{text}</Text>
</Center>
),
color: "green",
radius: "md",
autoClose: 1000,
icon: <IconCircleCheck color="white" />,
withCloseButton: false,
styles: (theme) => ({
description: { color: theme.white },
root: {
backgroundColor: theme.colors.green[7],
},
}),
});
}

View File

@@ -0,0 +1,31 @@
import { Center, Text } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconAlertTriangle } from "@tabler/icons-react";
/**
*
* @param text | masukan text untuk peringatan
* @type string
* @returns notifikasi peringatan
*/
export async function ComponentGlobal_NotifikasiGagal(text: string) {
return notifications.show({
message: (
<Center>
<Text fw={"bold"}>{text}</Text>
</Center>
),
color: "red",
radius: "md",
autoClose: 1000,
icon: <IconAlertTriangle color="white" />,
withCloseButton: false,
styles: (theme) => ({
description: { color: theme.white },
root: {
backgroundColor: theme.colors.red[7],
},
}),
});
}

View File

@@ -0,0 +1,31 @@
import { ActionIcon, Avatar, Center, Text } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconAlertTriangle } from "@tabler/icons-react";
/**
*
* @param text | masukan text untuk peringatan
* @type string
* @returns notifikasi peringatan
*/
export async function ComponentGlobal_NotifikasiPeringatan(text: string) {
return notifications.show({
message: (
<Center>
<Text fw={"bold"}>{text}</Text>
</Center>
),
color: "yellow.3",
radius: "md",
autoClose: 1000,
icon: <ActionIcon radius={"xl"} bg={"white"} p={3}><IconAlertTriangle color="red" /></ActionIcon>,
withCloseButton: false,
styles: (theme) => ({
description: { color: theme.white },
root: {
backgroundColor: theme.colors.yellow[7],
},
}),
});
}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
@@ -15,7 +15,7 @@ export default function LayoutMainCrowd({
return (
<>
<AppShell
header={<HeaderTamplate route="/dev/home" title="HIPMI Crowd Funding" />}
header={<ComponentGlobal_HeaderTamplate route="/dev/home" title="HIPMI Crowd Funding" />}
>
{children}
</AppShell>

View File

@@ -1,14 +1,14 @@
"use client"
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import { MODEL_USER } from "@/app_modules/home/model/interface";
import { Stack, Title, Paper, Group, ActionIcon, Avatar, Text } from "@mantine/core";
import { IconCircleChevronRight } from "@tabler/icons-react";
import _ from "lodash";
import { useRouter } from "next/navigation";
import ComponentDonasi_NotedBox from "../noted_box";
export default function ComponentDonasi_InformasiPenggalangMain({ author }: { author: MODEL_AUTHOR}) {
export default function ComponentDonasi_InformasiPenggalangMain({ author }: { author: MODEL_USER}) {
const router = useRouter();
return (
<>

View File

@@ -7,7 +7,7 @@ import {
MODEL_DONASI,
MODEL_DONASI_INFO_PENGGALANG,
} from "@/app_modules/donasi/model/interface";
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import { MODEL_USER } from "@/app_modules/home/model/interface";
import {
AspectRatio,
Avatar,
@@ -56,7 +56,7 @@ export default function PenggalangDanaDonasi({
);
}
function InformasiPenggalang({ value }: { value: MODEL_AUTHOR }) {
function InformasiPenggalang({ value }: { value: MODEL_USER }) {
return (
<>
<Paper radius={"md"}>

View File

@@ -1,4 +1,4 @@
import { MODEL_AUTHOR } from "@/app_modules/home/models/interface";
import { MODEL_USER } from "@/app_modules/home/model/interface";
import { Model_Nama_Bank } from "@/app_modules/investasi/model/model_investasi";
import { MODEL_IMAGES } from "@/app_modules/models/interface";
@@ -24,7 +24,7 @@ export interface MODEL_DONASI {
donasiMaster_DurasiId: string;
donasiMaster_StatusDonasiId: string;
CeritaDonasi: MODEL_CERITA_DONASI;
Author: MODEL_AUTHOR;
Author: MODEL_USER;
imageDonasi: MODEL_IMAGES;
DonasiMaster_Ketegori: MODEL_DONASI_ALL_MASTER;
DonasiMaster_Durasi: MODEL_DONASI_ALL_MASTER;
@@ -78,7 +78,7 @@ export interface MODEL_DONASI_INVOICE {
active: boolean;
createdAt: Date;
updatedAt: Date;
Author: MODEL_AUTHOR;
Author: MODEL_USER;
authorId: string;
donasiMaster_BankId: string;
donasiMaster_StatusInvoiceId: string;

View File

@@ -19,11 +19,14 @@ export async function funGetUserProfile( userId: string ) {
email: true,
jenisKelamin: true,
name: true,
imagesId: true,
ImageProfile: {
select: {
url: true,
},
},
ImagesBackground: true,
imagesBackgroundId: true,
},
},
},

View File

@@ -7,7 +7,7 @@ import { unsealData } from "iron-session";
import { redirect } from "next/navigation";
const config = yaml.parse(fs.readFileSync("config.yaml").toString());
export async function getToken_UserId() {
export async function User_getUserId() {
const c = cookies().get("ssn");
if (!c?.value) return redirect("/dev/auth/login");

View File

@@ -1,25 +0,0 @@
"use server";
import prisma from "@/app/lib/prisma";
import { getConfig } from "@/bin/config";
import { unsealData } from "iron-session";
import { cookies } from "next/headers";
import fs from "fs";
import yaml from "yaml";
const config = yaml.parse(fs.readFileSync("config.yaml").toString());
/**
* @returns token(id and username)
*/
export async function getToken() {
const c = cookies().get("ssn");
const token = await unsealData(c?.value as string, {
password: await config.server.password,
});
const data = JSON.parse(token as any)
return data;
}

View File

@@ -0,0 +1,17 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function User_getOneById(userId: string) {
const data = await prisma.user.findFirst({
where: {
id: userId,
},
select: {
id: true,
Profile: true,
},
});
return data;
}

View File

@@ -1,4 +1,4 @@
import HomeView from "./view";
import HomeLayout from "./layout";
import { getToken } from "./api/api-get-token";
export {HomeView, HomeLayout, getToken}
export {HomeView, HomeLayout}

View File

@@ -1,10 +1,59 @@
"use client";
import { ActionIcon, AppShell, Flex, Group, Header, Text } from "@mantine/core";
import {
ActionIcon,
AppShell,
Avatar,
Center,
Flex,
Footer,
Grid,
Group,
Header,
SimpleGrid,
Stack,
Text,
ThemeIcon,
} from "@mantine/core";
import { HomeView } from ".";
import { IconUserSearch, IconAward, IconQrcode } from "@tabler/icons-react";
import {
IconUserSearch,
IconAward,
IconQrcode,
IconUserCircle,
} from "@tabler/icons-react";
import { Logout } from "../auth";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { MODEL_USER } from "./model/interface";
import React, { useState } from "react";
import { useRouter } from "next/navigation";
import { ComponentGlobal_NotifikasiPeringatan } from "../component_global/notif_global/notifikasi_peringatan";
import { ComponentGlobal_NotifikasiBerhasil } from "../component_global/notif_global/notifikasi_berhasil";
import { RouterUserSearch } from "@/app/lib/router_hipmi/router_user_search";
export default function HomeLayout({
dataUser,
children,
}: {
dataUser: MODEL_USER;
children: React.ReactNode;
}) {
const router = useRouter();
const [user, setUser] = useState(dataUser);
const listFooter = [
{
id: 1,
name: "Temukan user",
icon: <IconUserSearch />,
link: ``,
},
{
id: 2,
name: "Profile",
icon: <IconUserCircle />,
link: RouterProfile.katalog,
},
];
export default function HomeLayout({ children }: { children: any }) {
return (
<>
<AppShell
@@ -12,9 +61,6 @@ export default function HomeLayout({ children }: { children: any }) {
<Header height={50} bg={"dark"}>
<Group position="apart" align="center" h={50} p={"sm"}>
<Group spacing={"sm"}>
<ActionIcon>
<IconUserSearch />
</ActionIcon>
<ActionIcon>
<IconAward />
</ActionIcon>
@@ -26,12 +72,57 @@ export default function HomeLayout({ children }: { children: any }) {
<ActionIcon>
<IconQrcode />
</ActionIcon>
<Logout />
</Group>
</Group>
</Header>
}
footer={
<Footer height={70} bg={"dark"}>
<Grid p={"xs"}>
<Grid.Col
span={"auto"}
onClick={() => {
if (user.Profile === null) {
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
} else {
// router.push(RouterProfile.katalog + `${user.Profile.id}`);
router.push(RouterUserSearch.main)
}
}}
>
<Stack align="center" spacing={0}>
<ActionIcon variant={"transparent"}>
<IconUserSearch color="white" />
</ActionIcon>
<Text fz={"xs"} c={"white"}>
Temukan pengguna
</Text>
</Stack>
</Grid.Col>
<Grid.Col
span={"auto"}
onClick={() => {
if (user.Profile === null) {
router.push(RouterProfile.create + `${user.id}`);
} else {
router.push(RouterProfile.katalog + `${user.Profile.id}`);
}
}}
>
<Stack align="center" spacing={0}>
<ActionIcon variant={"transparent"}>
{user.Profile === null ? <IconUserCircle color="white" /> : <Avatar radius={"xl"} size={20} src={RouterProfile.api_foto_profile + `${user.Profile.imagesId}`}/>}
</ActionIcon>
<Text fz={"xs"} c={"white"}>
Profile
</Text>
</Stack>
</Grid.Col>
</Grid>
</Footer>
}
>
{children}
</AppShell>
</>

View File

@@ -1,4 +1,6 @@
export interface MODEL_AUTHOR {
import { MODEL_PROFILE } from "@/app_modules/katalog/profile/model/interface";
export interface MODEL_USER {
id: string;
username: string;
nomor: string;
@@ -6,4 +8,6 @@ export interface MODEL_AUTHOR {
createdAt: Date;
updatedAt: Date;
masterUserRoleId: string;
Profile: MODEL_PROFILE
}

View File

@@ -1,4 +1,6 @@
export interface MODEL_User_profile {
import { MODEL_IMAGES } from "@/app_modules/models/interface";
export interface MODEL_PROFILE_OLD {
id: string;
username: string;
nomor: string;
@@ -8,8 +10,11 @@ export interface MODEL_User_profile {
email: string;
jenisKelamin: string;
name: string;
imagesId: string
ImageProfile: {
url: string;
} | null;
} | null;
}
imagesBackgroundId: string,
ImagesBackground: MODEL_IMAGES
}
}

View File

@@ -13,11 +13,6 @@ import {
ThemeIcon,
Title,
} from "@mantine/core";
import { Logout } from "../auth";
import { useState } from "react";
import { ApiHipmi } from "@/app/lib/api";
import { useShallowEffect } from "@mantine/hooks";
import { getToken } from "./api/api-get-token";
import {
IconAffiliate,
@@ -32,40 +27,28 @@ import {
} from "@tabler/icons-react";
import toast from "react-simple-toasts";
import { getProfile } from "../katalog/profile";
import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { gs_token } from "./state/global_state";
import { loadDataProfile } from "../katalog/profile/fun/fun_get_profile";
import {
gs_fotoProfile,
gs_profile,
} from "../katalog/profile/state/global_state";
import { gs_ListPortofolio } from "../katalog/portofolio/state/global_state";
import { myConsole } from "@/app/fun/my_console";
import { getFotoProfile } from "../katalog/profile/api/get-foto-profile";
import { funGetUserProfile } from "../fun/get_user_profile";
import { MODEL_User_profile } from "./models/user_profile";
import { MODEL_PROFILE_OLD } from "./model/user_profile";
import AppNotif from "../notif";
// export const dynamic = "force-dynamic"
// export const revalidate = 0
export default function HomeView({ user }: { user: MODEL_User_profile }) {
export default function HomeView() {
const router = useRouter();
const [stateUser, setStateUser] = useState(user);
// const [stateUser, setStateUser] = useState(user);
const listHalaman = [
{
id: 1,
name: "Forums",
icon: <IconMessages size={50} />,
link: "",
name: "Crowd Funding",
icon: <IconHeartHandshake size={50} />,
link: `/dev/crowd/splash`,
},
{
id: 2,
name: "Project Collaboration",
icon: <IconAffiliate size={50} />,
name: "Event",
icon: <IconPresentation size={50} />,
link: "",
},
{
@@ -76,15 +59,15 @@ export default function HomeView({ user }: { user: MODEL_User_profile }) {
},
{
id: 4,
name: "Event",
icon: <IconPresentation size={50} />,
name: "Project Collaboration",
icon: <IconAffiliate size={50} />,
link: "",
},
{
id: 5,
name: "Crowd Funding",
icon: <IconHeartHandshake size={50} />,
link: `/dev/crowd/splash`,
name: "Forums",
icon: <IconMessages size={50} />,
link: "",
},
{
id: 6,
@@ -109,7 +92,7 @@ export default function HomeView({ user }: { user: MODEL_User_profile }) {
return (
<>
<Box>
<Flex align={"center"} gap={"sm"}>
{/* <Flex align={"center"} gap={"sm"}>
<ActionIcon
size={30}
variant="transparent"
@@ -128,7 +111,7 @@ export default function HomeView({ user }: { user: MODEL_User_profile }) {
Welcome to ,{" "}
{stateUser.username ? stateUser.username : <Loader size={"xs"} />}
</Text>
</Flex>
</Flex> */}
<Paper bg={"dark"} radius={5} my={"xs"}>
<Image alt="logo" src={"/aset/investasi/home-hipmi.png"} />

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutBeritaInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Berita" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Berita" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -13,7 +13,7 @@ export default function InvestasiCreateLayout({
<>
<AppShell
header={
<HeaderTamplate title="Investasi Baru" />
<ComponentGlobal_HeaderTamplate title="Investasi Baru" />
}
>
{children}

View File

@@ -1,7 +1,7 @@
"use client";
import { Warna } from "@/app/lib/warna";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell, Button, Center, Footer } from "@mantine/core";
import { IconPencilPlus } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
@@ -20,7 +20,7 @@ export default function LayoutCreateBeritaInvestasi({
return (
<>
<AppShell
header={<HeaderTamplate title="Buat Berita" />}
header={<ComponentGlobal_HeaderTamplate title="Buat Berita" />}
// footer={
// <Footer height={70} sx={{ borderStyle: "none" }}>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft, IconEdit } from "@tabler/icons-react";
import { useRouter } from "next/navigation";

View File

@@ -31,8 +31,8 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_Investasi } from "../model/model_investasi";
import moment from "moment";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { RouterUserProfile } from "@/app/lib/router_hipmi/router_user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { gs_TransferValue } from "../g_state";
import { useAtom } from "jotai";
import _ from "lodash";
@@ -45,7 +45,7 @@ export default function DetailInvestasi({
totalInvestor,
}: {
dataInvestasi: MODEL_Investasi;
dataUser: MODEL_User_profile;
dataUser: MODEL_PROFILE_OLD;
loginUserId: string;
progress: number;
totalInvestor: number;

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutDetailBeritaInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Detail Berita" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Detail Berita" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutDetailDokumenInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Dokumen" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Dokumen" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
@@ -16,7 +16,7 @@ export default function LayoutDetailDraftInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
title="Detail Draft"
icon={<IconEdit />}
route2={`/dev/investasi/edit/${id}`}

View File

@@ -1,6 +1,6 @@
"use client"
import HeaderTamplate from "@/app_modules/component/header_tamplate"
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate"
import { AppShell } from "@mantine/core"
import React from "react"
@@ -9,7 +9,7 @@ export default function LayoutDetailPublishInvestasi({children}: {children: Reac
<AppShell
header={
<HeaderTamplate title="Detail Publish"/>
<ComponentGlobal_HeaderTamplate title="Detail Publish"/>
}
>
{children}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
@@ -16,7 +16,7 @@ export default function LayoutDetailRejecttInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
title="Detail Reject"
// icon={<IconEdit />}
// route2={`/dev/investasi/edit/${idInves}`}

View File

@@ -1,6 +1,6 @@
"use client"
import HeaderTamplate from "@/app_modules/component/header_tamplate"
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate"
import { AppShell } from "@mantine/core"
import React from "react"
@@ -9,7 +9,7 @@ export default function LayoutDetailReviewInvestasi({children}: {children: React
<AppShell
header={
<HeaderTamplate title="Detail Review"/>
<ComponentGlobal_HeaderTamplate title="Detail Review"/>
}
>
{children}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
@@ -16,7 +16,7 @@ export default function LayoutDetailProspektus({
const router = useRouter();
return (
<>
<AppShell header={<HeaderTamplate title="Prospektus" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Prospektus" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutDetailSahamTerbeli({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Saham Terbeli" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Saham Terbeli" />}>
{children}
</AppShell>
</>

View File

@@ -1,12 +1,12 @@
"use client"
import HeaderTamplate from "@/app_modules/component/header_tamplate"
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate"
import { AppShell } from "@mantine/core"
import React from "react"
export default function LayoutEditInvestasi({children}: {children: React.ReactNode}){
return<>
<AppShell header={<HeaderTamplate title="Edit Portofolio Investasi"/>}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Edit Portofolio Investasi"/>}>
{children}
</AppShell>
</>

View File

@@ -2,7 +2,7 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { Warna } from "@/app/lib/warna";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell, Button, Center, Footer } from "@mantine/core";
import { useRouter } from "next/navigation";
import React from "react";
@@ -17,7 +17,7 @@ export default function LayoutEditBeritaInvestasi({
return (
<>
<AppShell
header={<HeaderTamplate title="Edit Berita" />}
header={<ComponentGlobal_HeaderTamplate title="Edit Berita" />}
// footer={
// <Footer height={70} sx={{ borderStyle: "none" }}>

View File

@@ -1,7 +1,7 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
@@ -17,7 +17,7 @@ export default function LayoutEditDokumenInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
title="Edit Dokumen"
icon={<IconEdit />}
route2={RouterInvestasi.upload_dokumen + `${idInves}`}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell, Stack, Text } from "@mantine/core";
import React from "react";
@@ -13,7 +13,7 @@ export default function LayoutEditIntroInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Edit Intro" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Edit Intro" />}>
<Stack>
{children}
</Stack>

View File

@@ -1,7 +1,7 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
@@ -19,7 +19,7 @@ export default function LayoutEditProspektusInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
title="Edit Prospektus"
icon={<IconEdit />}
route2={RouterInvestasi.upload_prospektus + `${dataInvestasi.id}`}

View File

@@ -1,7 +1,7 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconPencilPlus } from "@tabler/icons-react";
import React from "react";
@@ -18,7 +18,7 @@ export default function LayoutListEditBeritaInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
title="List Berita"
icon={<IconPencilPlus />}
route2={RouterInvestasi.create_berita + `${idInves}`}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import {
ActionIcon,
AppShell,
@@ -66,7 +66,7 @@ export default function LayoutMainInvestasi({
<>
<AppShell
header={
<HeaderTamplate
<ComponentGlobal_HeaderTamplate
route="/dev/crowd/main"
title="Investasi"
// icon={<IconPencilPlus />}

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutMetodeTransferInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Pilih Metode Transfer" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Pilih Metode Transfer" />}>
{children}
</AppShell>
</>

View File

@@ -1,4 +1,4 @@
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
export interface MODEL_Investasi {
id: string;
@@ -27,7 +27,7 @@ export interface MODEL_Investasi {
masterPeriodeDevidenId: string;
masterPembagianDevidenId: string;
masterPencarianInvestorId: string;
author: MODEL_User_profile;
author: MODEL_PROFILE_OLD;
countDown: Date
}
@@ -48,7 +48,7 @@ export interface MODEL_Transaksi_Investasi {
merchant_name: string;
redirect_url: string;
token: string;
Author: MODEL_User_profile;
Author: MODEL_PROFILE_OLD;
masterStatusTransaksiInvestasiId: string;
investasiId: string;
Investasi: MODEL_Investasi;

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -13,7 +13,7 @@ export default function LayoutProsesInvestasi({
<>
<AppShell
header={
<HeaderTamplate title="Proses Investasi"/>
<ComponentGlobal_HeaderTamplate title="Proses Investasi"/>
}
>{children}</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { ActionIcon, AppShell, Box, Group, Header, Text } from "@mantine/core";
import { useAtom } from "jotai";
import React, { useState } from "react";

View File

@@ -15,7 +15,7 @@ import {
import { useFocusTrap, useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { MODEL_Investasi } from "../model/model_investasi";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
import { useEffect, useState } from "react";
import getTokenTransaksi from "../fun/get_token_transaksi";
import toast from "react-simple-toasts";

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import router from "next/router";

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell, Title } from "@mantine/core";
import React from "react";

View File

@@ -2,7 +2,7 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { Warna } from "@/app/lib/warna";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import {
ActionIcon,
AppShell,

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutUploadGambarInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Gambar Investasi" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Upload Gambar Investasi" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutBuktiTransferInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Bukti Transfer" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Upload Bukti Transfer" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutUploadDokumenInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Dokumen" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Upload Dokumen" />}>
{children}
</AppShell>
</>

View File

@@ -1,6 +1,6 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import ComponentGlobal_HeaderTamplate from "@/app_modules/component_global/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
@@ -11,7 +11,7 @@ export default function LayoutUploadProspektusInvestasi({
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Prospektus" />}>
<AppShell header={<ComponentGlobal_HeaderTamplate title="Upload Prospektus" />}>
{children}
</AppShell>
</>

View File

@@ -0,0 +1,71 @@
"use client";
import { Header, Group, ActionIcon, Text, Title } from "@mantine/core";
import { IconArrowLeft, IconChevronLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
export default function ComponentKatalog_HeaderTamplate({
hideBack,
changeIconBack,
route,
route2,
title,
icon,
bg,
titleColor,
}: {
hideBack?: boolean;
changeIconBack?: any;
route?: any;
route2?: any;
title: string;
icon?: any;
bg?: any;
titleColor?: string
}) {
const router = useRouter();
return (
<>
<Header
height={50}
sx={{ borderStyle: "none" }}
bg={bg === null ? "" : bg}
>
<Group h={50} position="apart" px={"md"}>
{hideBack ? (
<ActionIcon variant="transparent" disabled></ActionIcon>
) : (
<ActionIcon
variant="transparent"
onClick={() => {
if (route === null || route === undefined) {
return router.back();
} else {
return router.push(route);
}
}}
>
{changeIconBack ? changeIconBack : <IconChevronLeft />}
</ActionIcon>
)}
<Title order={5} c={titleColor ? titleColor : "black"} >{title}</Title>
{(() => {
if (route2 === null || route2 === undefined) {
return <ActionIcon disabled variant="transparent"></ActionIcon>;
} else {
return (
<ActionIcon
variant="transparent"
onClick={() => router.push(route2)}
>
{icon}
</ActionIcon>
);
}
})()}
</Group>
</Header>
</>
);
}

View File

@@ -0,0 +1,22 @@
import { Center, Grid, Group, Paper, Text, Title } from "@mantine/core";
export default function ComponentKatalog_NotedBox({
informasi,
}: {
informasi: string;
}) {
return (
<>
<Paper bg={"blue.3"} p={10}>
<Group>
<Text fz={10} fs={"italic"}>
<Text span inherit c={"red"}>
*{" "}
</Text>
{informasi}
</Text>
</Group>
</Paper>
</>
);
}

View File

@@ -2,36 +2,37 @@
import { Logout } from "@/app_modules/auth";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconUserSearch, IconAward, IconQrcode, IconArrowLeft, IconPencilPlus } from "@tabler/icons-react";
import {
IconUserSearch,
IconAward,
IconQrcode,
IconArrowLeft,
IconPencilPlus,
IconChevronLeft,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import ComponentKatalog_HeaderTamplate from "../component/header_tamplate";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
export default function KatalogLayout({ children, profileId }: { children: any, profileId: any }) {
const router = useRouter()
export default function KatalogLayout({
children,
profileId,
}: {
children: any;
profileId: any;
}) {
const router = useRouter();
return (
<>
<AppShell
header={
<Header height={50} bg={"dark"}>
<Group position="apart" align="center" h={50} p={"sm"}>
<Group spacing={"sm"}>
<ActionIcon variant="transparent" onClick={() => router.push("/dev/home")}>
<IconArrowLeft/>
</ActionIcon>
{/* <ActionIcon>
<IconAward />
</ActionIcon> */}
</Group>
<Text color="white" fw={"bold"}>
Katalog
</Text>
<Group spacing={"sm"}>
<ActionIcon variant="transparent" onClick={() => router.push(`/dev/portofolio/create/${profileId}`)}>
<IconPencilPlus />
</ActionIcon>
{/* <Logout /> */}
</Group>
</Group>
</Header>
<ComponentKatalog_HeaderTamplate
title="Katalog"
bg={"black"}
titleColor="white"
// route={RouterHome.main_home}
/>
}
>
{children}

View File

@@ -11,37 +11,38 @@ import {
Group,
Image,
Paper,
Stack,
Text,
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import {
IconAddressBook,
IconCamera,
IconEditCircle,
IconGenderFemale,
IconGenderMale,
IconHome,
IconMail,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { ProfileView, getProfile } from "../profile";
import { gs_profile } from "../profile/state/global_state";
import { myConsole } from "@/app/fun/my_console";
import { useAtom } from "jotai";
import { loadDataProfile } from "../profile/fun/fun_get_profile";
import { getFotoProfile } from "../profile/api/get-foto-profile";
import { ApiHipmi } from "@/app/lib/api";
import { ProfileView } from "../profile";
import { ListPortofolioView } from "../portofolio";
import { User } from "@prisma/client";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
import { LIST_PORTOFOLIO } from "@/app_modules/models/portofolio";
import User_Logout from "@/app_modules/auth/logout/view";
import { MODEL_PORTOFOLIO } from "../portofolio/model/interface";
import { MODEL_PROFILE } from "../profile/model/interface";
export default function KatalogView({
profile,
listPorto,
userLoginId,
}: {
profile: MODEL_PROFILE;
listPorto: LIST_PORTOFOLIO;
userLoginId: string;
}) {
export default function KatalogView({ user, listPorto }: { user: MODEL_User_profile, listPorto: LIST_PORTOFOLIO }) {
return (
<>
<ProfileView user={user} />
<ListPortofolioView listPorto={listPorto} />
<Stack>
<ProfileView profile={profile as any} userLoginId={userLoginId} />
<ListPortofolioView
listPorto={listPorto as any}
profile={profile}
userLoginId={userLoginId}
/>
{profile.User.id === userLoginId ? <User_Logout /> : ""}
</Stack>
</>
);
}

View File

@@ -3,6 +3,7 @@
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import ComponentKatalog_HeaderTamplate from "../../component/header_tamplate";
export default function CreatePortofolioLayout({ children, profileId }: { children: any, profileId: any }) {
const router = useRouter();
@@ -10,18 +11,7 @@ export default function CreatePortofolioLayout({ children, profileId }: { childr
<>
<AppShell
header={
<Header height={50} px={"sm"}>
<Group position="apart" h={50}>
<ActionIcon
variant="transparent"
onClick={() => router.push(`/dev/katalog/${profileId}`)}
>
<IconArrowLeft />
</ActionIcon>
<Text>Buat Portofolio</Text>
<ActionIcon variant="transparent"></ActionIcon>
</Group>
</Header>
<ComponentKatalog_HeaderTamplate title="Buat Portofolio"/>
}
>
{children}

View File

@@ -3,107 +3,227 @@
import { myConsole } from "@/app/fun/my_console";
import { ApiHipmi } from "@/app/lib/api";
import { Warna } from "@/app/lib/warna";
import { BIDANG_BISNIS } from "@/app_modules/models/portofolio";
import { Button, Select, Stack, TextInput, Title } from "@mantine/core";
import {
BIDANG_BISNIS_OLD,
MODEL_PORTOFOLIO_OLD,
} from "@/app_modules/models/portofolio";
import {
AspectRatio,
Button,
Center,
FileButton,
Image,
Paper,
Select,
Stack,
TextInput,
Textarea,
Title,
} from "@mantine/core";
import _ from "lodash";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import funCreatePortofolio from "../fun/fun_create_portofolio";
import { IconCamera } from "@tabler/icons-react";
import ComponentKatalog_NotedBox from "../../component/noted_box";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { NotifPeringatan } from "@/app_modules/donasi/component/notifikasi/notif_peringatan";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function CreatePortofolio({
bidangBisnis,
profileId,
}: {
bidangBisnis: BIDANG_BISNIS;
bidangBisnis: BIDANG_BISNIS_OLD;
profileId: any;
}) {
const router = useRouter();
const [value, setValue] = useState({
namaBisnis: "",
bidangBisnisId: "",
masterBidangBisnisId: "",
alamatKantor: "",
tlpn: "",
deskripsi: "",
});
async function onSubmit() {
const body = {
profileId: profileId,
namaBisnis: value.namaBisnis,
masterBidangBisnisId: value.bidangBisnisId,
alamatKantor: value.alamatKantor,
tlpn: value.tlpn,
deskripsi: value.deskripsi,
};
const [medsos, setMedsos] = useState({
facebook: "",
twitter: "",
instagram: "",
youtube: "",
tiktok: "",
});
if (_.values(body).includes("")) return toast("Lengkapi Data");
await funCreatePortofolio(body as any).then((res) => {
if (res.status === 201) {
toast("Berhasil disimpan");
return setTimeout(() => router.push(`/dev/katalog/${profileId}`), 1000)
} else {
return toast("Gagal disimpan");
}
});
}
const [file, setFile] = useState<File | any>(null);
const [img, setImg] = useState<any | null>(null);
return (
<>
{/* {JSON.stringify(profileId)} */}
<Stack px={"sm"}>
<TextInput
label="Nama Bisnis"
onChange={(val) => {
setValue({
...value,
namaBisnis: val.target.value,
});
}}
/>
<Select
label="Bidang Bisnis"
data={_.map(bidangBisnis as any).map((e: any) => ({
value: e.id,
label: e.name,
}))}
onChange={(val) => {
setValue({
...value,
bidangBisnisId: val as any,
});
}}
/>
<TextInput
label="Alamat Kantor"
onChange={(val) => {
setValue({
...value,
alamatKantor: val.target.value,
});
}}
/>
<TextInput
label="Nomor Telepon"
type="number"
onChange={(val) => {
setValue({
...value,
tlpn: val.target.value,
});
}}
/>
<TextInput
label="Deskripsi"
onChange={(val) => {
setValue({
...value,
deskripsi: val.target.value,
});
}}
/>
<Stack px={"sm"} spacing={50}>
<Stack spacing={"sm"}>
<ComponentKatalog_NotedBox informasi="Lengkapi Data Bisnis" />
<TextInput
withAsterisk
label="Nama Bisnis"
placeholder="Nama bisnis"
onChange={(val) => {
setValue({
...value,
namaBisnis: val.target.value,
});
}}
/>
<Select
withAsterisk
label="Bidang Bisnis"
placeholder="Pilih salah satu bidang bisnis"
data={_.map(bidangBisnis as any).map((e: any) => ({
value: e.id,
label: e.name,
}))}
onChange={(val) => {
setValue({
...value,
masterBidangBisnisId: val as any,
});
}}
/>
<TextInput
withAsterisk
label="Alamat Kantor"
placeholder="Alamat kantor"
onChange={(val) => {
setValue({
...value,
alamatKantor: val.target.value,
});
}}
/>
<TextInput
withAsterisk
label="Nomor Telepon Kantor"
placeholder="62 xxx xxx xxx"
type="number"
onChange={(val) => {
setValue({
...value,
tlpn: val.target.value,
});
}}
/>
<Textarea
autosize
minRows={2}
maxRows={5}
withAsterisk
label="Deskripsi"
placeholder="Deskripsi singkat mengenai usaha"
onChange={(val) => {
setValue({
...value,
deskripsi: val.target.value,
});
}}
/>
</Stack>
<Stack>
<ComponentKatalog_NotedBox informasi="Upload Logo Bisnis Anda!" />
<AspectRatio ratio={16 / 9}>
<Paper radius={"md"} withBorder>
<Image alt="Foto" src={img ? img : "/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Center>
<FileButton
onChange={async (files: any | null) => {
try {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
// console.log(buffer, "ini buffer");
// console.log(files, " ini file");
setImg(buffer);
setFile(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
variant="outline"
w={150}
leftIcon={<IconCamera />}
compact
>
Upload
</Button>
)}
</FileButton>
</Center>
</Stack>
<Stack>
<ComponentKatalog_NotedBox informasi="Isi hanya pada sosial media yang anda miliki" />
<TextInput
label="Facebook"
placeholder="Facebook"
onChange={(val) => {
setMedsos({
...medsos,
facebook: val.target.value,
});
}}
/>
<TextInput
label="Instagram"
placeholder="Instagram"
onChange={(val) => {
setMedsos({
...medsos,
instagram: val.target.value,
});
}}
/>
<TextInput
label="Tiktok"
placeholder="Tiktok"
onChange={(val) => {
setMedsos({
...medsos,
tiktok: val.target.value,
});
}}
/>
<TextInput
label="Twitter"
placeholder="Twitter"
onChange={(val) => {
setMedsos({
...medsos,
twitter: val.target.value,
});
}}
/>
<TextInput
label="Youtube"
placeholder="Youtube"
onChange={(val) => {
setMedsos({
...medsos,
youtube: val.target.value,
});
}}
/>
</Stack>
<Button
mt={"md"}
@@ -111,14 +231,46 @@ export default function CreatePortofolio({
bg={Warna.hijau_muda}
color="green"
onClick={() => {
onSubmit();
onSubmit(router, profileId, value as any, file, medsos);
}}
>
Simpan
</Button>
</Stack>
{/* <pre> {JSON.stringify(data, null, 2)}</pre> */}
{/* <pre> {JSON.stringify(bidangBisnis, null, 2)}</pre> */}
</>
);
}
async function onSubmit(
router: AppRouterInstance,
profileId: string,
dataPorto: MODEL_PORTOFOLIO_OLD,
file: FormData,
dataMedsos: any
) {
const porto = {
namaBisnis: dataPorto.namaBisnis,
masterBidangBisnisId: dataPorto.masterBidangBisnisId,
alamatKantor: dataPorto.alamatKantor,
tlpn: dataPorto.tlpn,
deskripsi: dataPorto.deskripsi,
};
if (_.values(porto).includes("")) return toast("Lengkapi Data");
if (!file) return NotifPeringatan("Lengkapi logo binnis");
const gambar = new FormData
gambar.append("file",file as any)
await funCreatePortofolio(profileId, porto as any, gambar, dataMedsos).then(
(res) => {
if (res.status === 201) {
ComponentGlobal_NotifikasiBerhasil("Berhasil disimpan");
router.back();
} else {
ComponentGlobal_NotifikasiGagal("Gagal disimpan");
}
}
);
}

View File

@@ -0,0 +1,130 @@
"use client";
import { Box, Button, Select, Stack, TextInput, Textarea } from "@mantine/core";
import {
MODEL_PORTOFOLIO,
MODEL_PORTOFOLIO_BIDANG_BISNIS,
} from "../../model/interface";
import { useState } from "react";
import _ from "lodash";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { useRouter } from "next/navigation";
import { Portofolio_funEditDataBisnis } from "../../fun/edit/fun_edit_data_bisnis_by_id";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function Portofolio_EditDataBisnis({
dataPorto,
listBidang,
}: {
dataPorto: MODEL_PORTOFOLIO;
listBidang: MODEL_PORTOFOLIO_BIDANG_BISNIS[];
}) {
const router = useRouter();
const [porto, setPorto] = useState(dataPorto);
// const [value, setPorto] = useState({
// namaBisnis: "",
// masterBidangBisnisId: "",
// alamatKantor: "",
// tlpn: "",
// deskripsi: "",
// });
return (
<>
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
<Stack spacing={50} p={"md"}>
<Stack>
<TextInput
withAsterisk
value={porto.namaBisnis}
label="Nama Bisnis"
placeholder="Nama bisnis"
onChange={(val) => {
setPorto({
...porto,
namaBisnis: val.target.value,
});
}}
/>
<Select
withAsterisk
value={porto.MasterBidangBisnis.id}
label="Bidang Bisnis"
placeholder="Pilih salah satu bidang bisnis"
data={listBidang.map((e) => ({
value: e.id,
label: e.name,
}))}
onChange={(val) => {
setPorto({
...(porto as any),
MasterBidangBisnis: {
id: val,
},
});
}}
/>
<TextInput
withAsterisk
value={porto.alamatKantor}
label="Alamat Kantor"
placeholder="Alamat kantor"
onChange={(val) => {
setPorto({
...porto,
alamatKantor: val.target.value,
});
}}
/>
<TextInput
withAsterisk
value={porto.tlpn}
label="Nomor Telepon Kantor"
placeholder="62 xxx xxx xxx"
type="number"
onChange={(val) => {
setPorto({
...porto,
tlpn: val.target.value,
});
}}
/>
<Textarea
autosize
minRows={2}
maxRows={5}
withAsterisk
value={porto.deskripsi}
label="Deskripsi"
placeholder="Deskripsi singkat mengenai usaha"
onChange={(val) => {
setPorto({
...porto,
deskripsi: val.target.value,
});
}}
/>
</Stack>
<Button
radius={"xl"}
onClick={() => {
onUpdate(router, porto as any);
}}
>
Update
</Button>
</Stack>
</>
);
}
async function onUpdate(router: AppRouterInstance, data: MODEL_PORTOFOLIO) {
await Portofolio_funEditDataBisnis(data).then((res) => {
if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message);
router.back();
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}

View File

@@ -0,0 +1,22 @@
"use client";
import ComponentKatalog_HeaderTamplate from "@/app_modules/katalog/component/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
export default function LayoutPortofolio_EditDataBisnis({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell
header={<ComponentKatalog_HeaderTamplate title="Edit Data Bisnis" />}
>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,21 @@
"use client";
import { AppShell } from "@mantine/core";
import React from "react";
import ComponentKatalog_HeaderTamplate from "../../component/header_tamplate";
export default function LayoutPortofolio_EditBisnis({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell
header={<ComponentKatalog_HeaderTamplate title="Edit Portofolio" />}
>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,113 @@
"use client";
import {
RouterPortofolio,
RouterProfile,
} from "@/app/lib/router_hipmi/router_katalog";
import {
AspectRatio,
Box,
Button,
Center,
FileButton,
Image,
Paper,
Stack,
} from "@mantine/core";
import { IconCamera } from "@tabler/icons-react";
import { profile } from "console";
import image from "next/image";
import { useRouter } from "next/navigation";
import router from "next/router";
import { useState } from "react";
import { MODEL_PORTOFOLIO } from "../../model/interface";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Portofolio_funEditLogoBisnisById } from "../../fun/edit/fun_edit_logo_bisnis_by_id";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function Portofolio_EditLogoBisnis({
dataPorto,
}: {
dataPorto: MODEL_PORTOFOLIO;
}) {
const router = useRouter();
const [file, setFile] = useState<File | null>(null);
const [image, setImage] = useState<any | null>(null);
return (
<>
<Stack spacing={"xl"} px={"sm"}>
<Paper p={"sm"} withBorder radius={"sm"} shadow="lg">
<Stack>
<AspectRatio ratio={1 / 1}>
<Image
alt="Foto"
src={
image
? image
: RouterPortofolio.api_logo_porto + `${dataPorto.logoId}`
}
/>
</AspectRatio>
<Center>
<FileButton
onChange={async (files: any | null) => {
try {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
// console.log(buffer, "ini buffer");
// console.log(files, " ini file");
setImage(buffer);
setFile(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
variant="outline"
w={150}
leftIcon={<IconCamera />}
compact
>
Upload
</Button>
)}
</FileButton>
</Center>
</Stack>
</Paper>
<Button
radius={"xl"}
onClick={() => onUpdate(router, dataPorto.id, file as any)}
>
Simpan
</Button>
</Stack>
</>
);
}
async function onUpdate(
router: AppRouterInstance,
portoId: string,
file: FormData
) {
const gambar = new FormData();
gambar.append("file", file as any);
await Portofolio_funEditLogoBisnisById(portoId, gambar).then((res) => {
if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message);
router.back();
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}

View File

@@ -0,0 +1,21 @@
"use client";
import ComponentKatalog_HeaderTamplate from "@/app_modules/katalog/component/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
export default function LayoutPortofolio_EditLogoBisnis({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell
header={<ComponentKatalog_HeaderTamplate title="Edit Logo Bisnis" />}
>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,107 @@
"use client";
import ComponentKatalog_NotedBox from "@/app_modules/katalog/component/noted_box";
import { Box, Button, Paper, Stack, TextInput } from "@mantine/core";
import { useState } from "react";
import { MODEL_PORTOFOLIO_MEDSOS } from "../../model/interface";
import { Portofolio_funEditMedsosById } from "../../fun/edit/fun_edit_medsos_bisnis_by_id";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { useRouter } from "next/navigation";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function Portofolio_EditMedsosBisnis({
dataMedsos,
}: {
dataMedsos: MODEL_PORTOFOLIO_MEDSOS;
}) {
const router = useRouter();
const [medsos, setMedsos] = useState(dataMedsos);
return (
<>
<pre>{JSON.stringify(dataMedsos, null, 2)}</pre>
<Paper shadow="lg" p={"sm"}>
<Stack px={"sm"}>
<TextInput
label="Facebook"
value={medsos.facebook}
placeholder="Facebook"
onChange={(val) => {
setMedsos({
...medsos,
facebook: val.target.value,
});
}}
/>
<TextInput
label="Instagram"
value={medsos.instagram}
placeholder="Instagram"
onChange={(val) => {
setMedsos({
...medsos,
instagram: val.target.value,
});
}}
/>
<TextInput
label="Tiktok"
value={medsos.tiktok}
placeholder="Tiktok"
onChange={(val) => {
setMedsos({
...medsos,
tiktok: val.target.value,
});
}}
/>
<TextInput
label="Twitter"
value={medsos.twitter}
placeholder="Twitter"
onChange={(val) => {
setMedsos({
...medsos,
twitter: val.target.value,
});
}}
/>
<TextInput
label="Youtube"
value={medsos.youtube}
placeholder="Youtube"
onChange={(val) => {
setMedsos({
...medsos,
youtube: val.target.value,
});
}}
/>
<Button
mt={"xl"}
radius={"xl"}
onClick={() => onUpdate(router, medsos)}
>
Update
</Button>
</Stack>
</Paper>
</>
);
}
async function onUpdate(
router: AppRouterInstance,
medsos: MODEL_PORTOFOLIO_MEDSOS
) {
await Portofolio_funEditMedsosById(medsos).then((res) => {
if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message);
router.back();
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}

View File

@@ -0,0 +1,21 @@
"use client";
import ComponentKatalog_HeaderTamplate from "@/app_modules/katalog/component/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
export default function LayoutPortofolio_EditMedsosBisnis({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell
header={<ComponentKatalog_HeaderTamplate title="Edit Media Sosial" />}
>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,51 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PORTOFOLIO } from "../../model/interface";
import fs from "fs";
import { revalidatePath } from "next/cache";
export async function Portofolio_funDeletePortofolioById(
data: MODEL_PORTOFOLIO
) {
const findLogo = await prisma.images.findFirst({
where: {
id: data.logoId,
},
select: {
id: true,
url: true,
},
});
if (findLogo) fs.unlinkSync(`./public/portofolio/logo/${findLogo.url}`);
const deleteLogo = await prisma.images.delete({
where: {
id: data.logoId,
},
});
if (!deleteLogo) return { status: 400, message: "Gagal hapus data logo" };
const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({
where: {
portofolioId: data.id,
},
});
if (!deletePortoMedsos)
return { status: 400, message: "Gagal hapus data medsos" };
const deletePortofolio = await prisma.portofolio.delete({
where: {
id: data.id,
},
});
if (!deletePortofolio)
return { status: 400, message: "Gagal hapus portofolio" };
revalidatePath("/dev/katalog");
return {
status: 200,
message: "Berhasil hapus portofolio",
};
}

View File

@@ -0,0 +1,27 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PORTOFOLIO } from "../../model/interface";
import { revalidatePath } from "next/cache";
export async function Portofolio_funEditDataBisnis(data: MODEL_PORTOFOLIO) {
const res = await prisma.portofolio.update({
where: {
id: data.id,
},
data: {
namaBisnis: data.namaBisnis,
alamatKantor: data.alamatKantor,
tlpn: data.tlpn,
deskripsi: data.deskripsi,
masterBidangBisnisId: data.MasterBidangBisnis.id,
},
});
if (!res) return { status: 400, message: "Gagal update" };
revalidatePath("/dev/portofolio/main/")
return {
status: 200,
message: "Update berhasil",
};
}

View File

@@ -0,0 +1,49 @@
"use server";
import prisma from "@/app/lib/prisma";
import _ from "lodash";
import { v4 } from "uuid";
import fs from "fs";
import { revalidatePath } from "next/cache";
export async function Portofolio_funEditLogoBisnisById(
portoId: string,
file: FormData
) {
const gambar: any = file.get("file");
const fileName = gambar.name;
const fileExtension = _.lowerCase(gambar.name.split(".").pop());
const randomNameFile = v4(fileName) + "." + fileExtension;
const upload = await prisma.images.create({
data: {
url: randomNameFile,
label: "PORTOFOLIO_LOGO",
},
select: {
id: true,
url: true,
},
});
if (!upload) return { status: 400, message: "Gagal upload gambar" };
const upload_toFolder = Buffer.from(await gambar.arrayBuffer());
fs.writeFileSync(`./public/portofolio/logo/${upload.url}`, upload_toFolder);
const updatePorto = await prisma.portofolio.update({
where: {
id: portoId,
},
data: {
logoId: upload.id,
},
});
if (!updatePorto) return { status: 200, message: "Update gagal" };
revalidatePath("/dev/portofolio/edit/logo");
revalidatePath("/dev/portofolio/main");
return {
status: 200,
message: "Berhasil mengubah Logo Bisnis!",
};
}

View File

@@ -0,0 +1,29 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PORTOFOLIO_MEDSOS } from "../../model/interface";
import { revalidatePath } from "next/cache";
export async function Portofolio_funEditMedsosById(
data: MODEL_PORTOFOLIO_MEDSOS
) {
const res = await prisma.portofolio_MediaSosial.update({
where: {
id: data.id,
},
data: {
facebook: data.facebook,
instagram: data.instagram,
tiktok: data.tiktok,
twitter: data.twitter,
youtube: data.youtube,
},
});
if (!res) return { status: 400, message: "Gagal update" };
revalidatePath("/dev/portofolio/main");
return {
status: 200,
message: "Berhasil update",
};
}

View File

@@ -1,32 +1,70 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PORTOFOLIO } from "@/app_modules/models/portofolio";
import { MODEL_PORTOFOLIO_OLD } from "@/app_modules/models/portofolio";
import { revalidatePath } from "next/cache";
import { MODEL_PORTOFOLIO, MODEL_PORTOFOLIO_MEDSOS } from "../model/interface";
import _ from "lodash";
import { v4 } from "uuid";
import fs from "fs";
export default async function funCreatePortofolio(data: MODEL_PORTOFOLIO) {
console.log(data);
export default async function funCreatePortofolio(
profileId: string,
data: MODEL_PORTOFOLIO,
file: FormData,
medsos: MODEL_PORTOFOLIO_MEDSOS
) {
const gambar: any = file.get("file");
const fileName = gambar.name;
const fileExtension = _.lowerCase(gambar.name.split(".").pop());
const fRandomName = v4(fileName) + "." + fileExtension;
const res = await prisma.katalog.create({
const upload = await prisma.images.create({
data: {
profileId: data.profileId,
url: fRandomName,
label: "PORTOFOLIO_LOGO",
},
select: {
id: true,
url: true,
},
});
if (!upload) return { status: 400, message: "Gagal upload logo portofolio" };
const upload_Folder = Buffer.from(await gambar.arrayBuffer());
fs.writeFileSync(`./public/portofolio/logo/${upload.url}`, upload_Folder);
const createProto = await prisma.portofolio.create({
data: {
profileId: profileId,
namaBisnis: data.namaBisnis,
deskripsi: data.deskripsi,
tlpn: data.tlpn,
alamatKantor: data.alamatKantor,
masterBidangBisnisId: data.masterBidangBisnisId,
logoId: upload.id,
},
});
if (!res)
return {
status: 401,
success: false,
};
if (!createProto) return { status: 400, message: "Gagal membuat portofolio" };
revalidatePath(`/dev/katalog/${data.profileId}`);
const createMedsos = await prisma.portofolio_MediaSosial.create({
data: {
portofolioId: createProto.id,
facebook: medsos.facebook,
instagram: medsos.instagram,
tiktok: medsos.tiktok,
twitter: medsos.twitter,
youtube: medsos.youtube,
},
});
if (!createMedsos)
return { status: 400, message: "Gagal menambahkan medsos" };
revalidatePath(`/dev/katalog`);
return {
status: 201,
success: true,
message: "Berhasil menambahakan portofolio",
};
}

View File

@@ -1,5 +1,5 @@
import toast from "react-simple-toasts";
import { funGetListPortofolio } from "./get_list_portofolio";
import { funGetListPortofolio } from "./get/get_list_portofolio";
/**
*

View File

@@ -3,18 +3,13 @@
import prisma from "@/app/lib/prisma";
export async function funGetListPortofolio(profileId: any) {
const data = await prisma.katalog.findMany({
const data = await prisma.portofolio.findMany({
where: {
profileId: profileId,
},
select: {
id: true,
namaBisnis: true,
alamatKantor: true,
tlpn: true,
deskripsi: true,
masterBidangBisnisId: true,
active: true,
profileId: true
},
});

View File

@@ -0,0 +1,13 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Portofolio_geOnetMedsosById(portoId: string) {
const data = await prisma.portofolio_MediaSosial.findFirst({
where: {
portofolioId: portoId,
},
});
return data;
}

View File

@@ -2,11 +2,11 @@
import prisma from "@/app/lib/prisma";
export async function getOnePortofolio(id: string) {
export async function Portofolio_getOneById(portoId: string) {
// console.log(id)
const data = await prisma.katalog.findUnique({
const data = await prisma.portofolio.findUnique({
where: {
id: id,
id: portoId,
},
select: {
id: true,
@@ -15,6 +15,10 @@ export async function getOnePortofolio(id: string) {
deskripsi: true,
tlpn: true,
active: true,
profileId: true,
Logo: true,
logoId: true,
masterBidangBisnisId: true,
MasterBidangBisnis: {
select: {
id: true,
@@ -22,7 +26,11 @@ export async function getOnePortofolio(id: string) {
active: true,
},
},
profileId: true,
Portofolio_MediaSosial: true,
},
});

View File

@@ -1,9 +0,0 @@
"use server"
import { myConsole } from "@/app/fun/my_console"
import prisma from "@/app/lib/prisma"
export async function getBidangBisnis() {
const data = await prisma.masterBidangBisnis.findMany()
return data
}

View File

@@ -0,0 +1,9 @@
"use server";
import { myConsole } from "@/app/fun/my_console";
import prisma from "@/app/lib/prisma";
export async function Portofolio_getMasterBidangBisnis() {
const data = await prisma.masterBidangBisnis.findMany();
return data;
}

View File

@@ -3,5 +3,25 @@ import CreatePortofolioLayout from "./create/layout";
import ListPortofolioView from "./list_view/view";
import PortofolioLayout from "./main/layout";
import ViewPortofolio from "./main/view";
import Portofolio_EditDataBisnis from "./edit/data";
import Portofolio_EditLogoBisnis from "./edit/logo";
import Portofolio_EditMedsosBisnis from "./edit/medsos";
import LayoutPortofolio_EditBisnis from "./edit/layout";
import LayoutPortofolio_EditDataBisnis from "./edit/data/layout";
import LayoutPortofolio_EditLogoBisnis from "./edit/logo/layout";
import LayoutPortofolio_EditMedsosBisnis from "./edit/medsos/layout";
export {CreatePortofolio, CreatePortofolioLayout, ListPortofolioView, PortofolioLayout, ViewPortofolio}
export {
CreatePortofolio,
CreatePortofolioLayout,
ListPortofolioView,
PortofolioLayout,
ViewPortofolio,
Portofolio_EditDataBisnis,
Portofolio_EditLogoBisnis,
Portofolio_EditMedsosBisnis,
LayoutPortofolio_EditBisnis,
LayoutPortofolio_EditDataBisnis,
LayoutPortofolio_EditLogoBisnis,
LayoutPortofolio_EditMedsosBisnis,
};

View File

@@ -1,44 +1,78 @@
"use client";
import { Box, Center, Grid, Paper, Text, Title } from "@mantine/core";
import {
ActionIcon,
Box,
Center,
Grid,
Group,
Paper,
Stack,
Text,
Title,
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useState } from "react";
import _ from "lodash";
import { IconCaretRightFilled } from "@tabler/icons-react";
import { loadDataProfile } from "../../profile/fun/fun_get_profile";
import { useAtom } from "jotai";
import { gs_profile } from "../../profile/state/global_state";
import { gs_ListPortofolio } from "../state/global_state";
import { myConsole } from "@/app/fun/my_console";
import { getProfile } from "../../profile";
import {
IconCaretRightFilled,
IconCirclePlus,
IconPencilPlus,
} from "@tabler/icons-react";
import { LIST_PORTOFOLIO } from "@/app_modules/models/portofolio";
import { useRouter } from "next/navigation";
import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog";
import { Warna } from "@/app/lib/warna";
import { MODEL_PROFILE } from "../../profile/model/interface";
export default function ListPortofolioView({
listPorto,
profile,
userLoginId,
}: {
listPorto: LIST_PORTOFOLIO;
listPorto: LIST_PORTOFOLIO[];
profile: MODEL_PROFILE;
userLoginId: string;
}) {
const router = useRouter();
const [porto, setPorto] = useState(listPorto);
return (
<>
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
<Center>
<Title order={4}>Portofolio</Title>
</Center>
<Box mt={"md"}>
{(() => {
if (porto) {
return (
<>
{" "}
{_.map(porto as any).map((e: any) => (
<Paper p={"sm"} shadow="lg" withBorder bg={"gray.1"}>
<Stack spacing={"md"}>
<Group position="apart">
<ActionIcon variant="transparent" disabled></ActionIcon>
<Title order={4}>Portofolio</Title>
{profile.User.id === userLoginId ? (
<ActionIcon
variant="transparent"
onClick={() =>
router.push(RouterPortofolio.create + `${profile.id}`)
}
>
<IconPencilPlus color={Warna.biru} />
</ActionIcon>
) : (
<ActionIcon variant="transparent" disabled></ActionIcon>
)}
</Group>
<Box>
{_.isEmpty(porto) ? (
<Center>
<Text fs={"italic"} fz={"xs"}>
- Belum Ada Portofolio -
</Text>
</Center>
) : (
<Box>
{porto.map((e: any) => (
<Paper
key={e.id}
h={50}
bg={"gray"}
my={"md"}
radius={50}
mb={"lg"}
radius={"md"}
onClick={() => router.push(`/dev/portofolio/main/${e.id}/`)}
>
<Grid h={50} align="center" px={"md"}>
@@ -51,13 +85,11 @@ export default function ListPortofolioView({
</Grid>
</Paper>
))}
</>
);
} else {
return <></>;
}
})()}
</Box>
</Box>
)}
</Box>
</Stack>
</Paper>
</>
);
}

View File

@@ -1,31 +1,89 @@
"use client";
import { ActionIcon, AppShell } from "@mantine/core";
import {
ActionIcon,
AppShell,
Button,
Group,
Header,
Modal,
Stack,
Title,
} from "@mantine/core";
import HeaderTransparent from "../../component/header_transparent";
import { useRouter } from "next/navigation";
import { IconArrowLeft, IconEdit } from "@tabler/icons-react";
import { IconArrowLeft, IconChevronLeft, IconEdit } from "@tabler/icons-react";
import ComponentKatalog_HeaderTamplate from "../../component/header_tamplate";
import { title } from "process";
import { useDisclosure } from "@mantine/hooks";
import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog";
export default function PortofolioLayout({ children, profileId }: { children: any, profileId: any }) {
export default function PortofolioLayout({
children,
portoId,
}: {
children: any;
portoId: any;
}) {
const router = useRouter();
const [opened, { open, close }] = useDisclosure(false);
return (
<>
<AppShell
header={
<HeaderTransparent
route={`/dev/katalog/${profileId}`}
title="Portofolio"
icon2={
<Header height={50} sx={{ borderStyle: "none" }}>
<Group h={50} position="apart" px={"md"}>
<ActionIcon
variant="transparent"
onClick={() => router.push("/dev/portofolio/edit")}
onClick={() => {
router.back();
}}
>
<IconChevronLeft />
</ActionIcon>
<Title order={5}>Detail Portofolio</Title>
<ActionIcon variant="transparent" onClick={() => open()}>
<IconEdit />
</ActionIcon>
}
/>
</Group>
</Header>
}
>
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
<Stack>
<Title order={6}>Anda ingin mengupdate Detail Bisnis ?</Title>
<Button
radius={"xl"}
variant="outline"
onClick={() => {
router.push(RouterPortofolio.edit_data_bisnis + `${portoId}`);
}}
>
Data Bisnis
</Button>
<Button
radius={"xl"}
variant="outline"
color="green"
onClick={() => {
router.push(RouterPortofolio.edit_logo_bisnis + `${portoId}`);
}}
>
Logo Bisnis
</Button>
<Button
radius={"xl"}
variant="outline"
color="orange"
onClick={() => {
router.push(RouterPortofolio.edit_medsos_bisnis + `${portoId}`);
}}
>
Media Sosial
</Button>
</Stack>
</Modal>
{children}
</AppShell>
</>

View File

@@ -1,11 +1,50 @@
"use client";
import {
RouterPortofolio,
RouterProfile,
} from "@/app/lib/router_hipmi/router_katalog";
import { Warna } from "@/app/lib/warna";
import { MODEL_PORTOFOLIO } from "@/app_modules/models/portofolio";
import { Box, Button, Center, Text, Title } from "@mantine/core";
import { IconTrash } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { MODEL_PORTOFOLIO_OLD } from "@/app_modules/models/portofolio";
import {
AspectRatio,
Box,
Button,
Center,
Grid,
Group,
Image,
Modal,
Paper,
Stack,
Text,
Title,
} from "@mantine/core";
import {
IconBrandFacebook,
IconBrandInstagram,
IconBrandTiktok,
IconBrandTwitter,
IconBrandYoutube,
IconBuilding,
IconBuildingSkyscraper,
IconListDetails,
IconMapPin,
IconNotes,
IconPhoneCall,
IconPinned,
IconTrash,
} from "@tabler/icons-react";
import { redirect, useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_PORTOFOLIO } from "../model/interface";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { Portofolio_getOneById } from "../fun/get/get_one_portofolio";
import _ from "lodash";
import { Portofolio_funDeletePortofolioById } from "../fun/delete/fun_delete_by_id";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function ViewPortofolio({
dataPorto,
@@ -14,21 +53,178 @@ export default function ViewPortofolio({
}) {
const router = useRouter();
const [porto, setPorto] = useState(dataPorto);
const [opened, { open, close }] = useDisclosure(false);
return (
<>
<Box>
<Text>{porto.namaBisnis}</Text>
<Text>{porto.alamatKantor}</Text>
<Text>+{porto.tlpn}</Text>
<Text>{porto.deskripsi}</Text>
<Text>{porto.MasterBidangBisnis.name}</Text>
</Box>
<Center mt={"md"}>
<Button bg={"red"} color="red" w={300} onClick={() => {}}>
{/* <pre>{JSON.stringify(porto, null, 2)}</pre> */}
<Stack>
<Paper p={"sm"} withBorder shadow="lg">
<Title order={6}>Data Bisnis</Title>
<Stack p={"sm"}>
<Grid>
<Grid.Col span={2}>
<IconBuildingSkyscraper />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text truncate>{dataPorto.namaBisnis}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconPhoneCall />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>+{dataPorto.tlpn}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconMapPin />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{dataPorto.alamatKantor}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconListDetails />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{dataPorto.MasterBidangBisnis.name}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconPinned />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{dataPorto.deskripsi}</Text>
</Grid.Col>
</Grid>
</Stack>
</Paper>
<Paper p={"sm"} withBorder shadow="lg">
<Title order={6}>Logo Bisnis</Title>
<AspectRatio ratio={1 / 1}>
<Paper>
<Image
alt="Foto"
src={RouterPortofolio.api_logo_porto + `${dataPorto.logoId}`}
/>
</Paper>
</AspectRatio>
</Paper>
<Paper p={"sm"} withBorder shadow="lg">
<Title order={6}>Media Sosial Bisnis</Title>
<Stack p={"sm"}>
<Grid>
<Grid.Col span={2}>
<IconBrandFacebook />
</Grid.Col>
<Grid.Col span={"auto"}>
{dataPorto.Portofolio_MediaSosial.facebook ? (
<Text>{dataPorto.Portofolio_MediaSosial.facebook}</Text>
) : (
"-"
)}
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconBrandInstagram />
</Grid.Col>
<Grid.Col span={"auto"}>
{dataPorto.Portofolio_MediaSosial.instagram ? (
<Text>{dataPorto.Portofolio_MediaSosial.instagram}</Text>
) : (
"-"
)}
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconBrandTiktok />
</Grid.Col>
<Grid.Col span={"auto"}>
{dataPorto.Portofolio_MediaSosial.tiktok ? (
<Text>{dataPorto.Portofolio_MediaSosial.tiktok}</Text>
) : (
"-"
)}
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconBrandTwitter />
</Grid.Col>
<Grid.Col span={"auto"}>
{dataPorto.Portofolio_MediaSosial.twitter ? (
<Text>{dataPorto.Portofolio_MediaSosial.twitter}</Text>
) : (
"-"
)}
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconBrandYoutube />
</Grid.Col>
<Grid.Col span={"auto"}>
{dataPorto.Portofolio_MediaSosial.youtube ? (
<Text>{dataPorto.Portofolio_MediaSosial.youtube}</Text>
) : (
"-"
)}
</Grid.Col>
</Grid>
</Stack>
</Paper>
<Button
radius={"xl"}
bg={"red"}
color="red"
onClick={() => {
open();
}}
>
<IconTrash />
</Button>{" "}
</Center>
</Button>
</Stack>
<Modal opened={opened} onClose={close} centered withCloseButton={false}>
<Stack>
<Title order={6}>Anda yakin menghapus portofolio ini ?</Title>
<Group position="center">
<Button radius={"xl"} onClick={() => close()}>
Batal
</Button>
<Button
radius={"xl"}
color="red"
onClick={() => onDelete(router, dataPorto as any)}
>
Hapus
</Button>
</Group>
</Stack>
</Modal>
</>
);
}
async function onDelete(
router: AppRouterInstance,
dataPorto: MODEL_PORTOFOLIO
) {
await Portofolio_funDeletePortofolioById(dataPorto).then((res) => {
if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message);
router.push(RouterProfile.katalog + `${dataPorto.profileId}`);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}

View File

@@ -0,0 +1,35 @@
import { MODEL_IMAGES } from "@/app_modules/models/interface";
export interface MODEL_PORTOFOLIO {
id: string;
namaBisnis: string;
alamatKantor: string;
deskripsi: string;
tlpn: string;
active: boolean;
MasterBidangBisnis: MODEL_PORTOFOLIO_BIDANG_BISNIS;
masterBidangBisnisId: string;
profileId: string;
Logo: MODEL_IMAGES;
logoId: string;
Portofolio_MediaSosial: MODEL_PORTOFOLIO_MEDSOS
}
export interface MODEL_PORTOFOLIO_BIDANG_BISNIS {
id: string;
name: string;
active: boolean;
}
export interface MODEL_PORTOFOLIO_MEDSOS {
id: string
facebook: string
twitter: string
instagram: string
tiktok: string;
youtube:string
active: boolean
createdAt: Date
updatedAt:Date
portofolioId: string
};

View File

@@ -1,16 +0,0 @@
"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;
}

View File

@@ -1,38 +0,0 @@
"use server";
import { myConsole } from "@/app/fun/my_console";
import prisma from "@/app/lib/prisma";
import { getToken } from "@/app_modules/home";
import { NextResponse } from "next/server";
/**
* @function api get data profile by user id
* @returns data profile
*/
export async function getProfile() {
const token = await getToken();
const dataProfile = await prisma.profile.findUnique({
where: {
userId: token.id,
},
select: {
id: true,
name: true,
email: true,
alamat: true,
jenisKelamin: true,
active: true,
imagesId: true,
User: {
select : {
username: true,
nomor: true
}
}
},
});
return dataProfile;
}

View File

@@ -18,7 +18,7 @@ export default function ProfileLayout({ children }: { children: any }) {
<AppShell
header={
<Header height={50} px={"sm"}>
<Header height={50} px={"sm"} sx={{borderBlockStyle: "none"}}>
<Group position="apart" h={50}>
<ActionIcon variant="transparent" onClick={() => router.push("/dev/home")}>
<IconArrowLeft />

View File

@@ -3,17 +3,40 @@
import { myConsole } from "@/app/fun/my_console";
import { ApiHipmi } from "@/app/lib/api";
import { Warna } from "@/app/lib/warna";
import { gs_token } from "@/app_modules/home/state/global_state";
import { Button, Select, Stack, TextInput } from "@mantine/core";
import {
AspectRatio,
Avatar,
Box,
Button,
Center,
FileButton,
Image,
Paper,
Select,
Stack,
TextInput,
} from "@mantine/core";
import { useAtom } from "jotai";
import _ from "lodash";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import funCreateNewProfile from "../fun/fun_create_profile";
import { IconCamera } from "@tabler/icons-react";
import ComponentKatalog_NotedBox from "../../component/noted_box";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { MODEL_PROFILE } from "../model/interface";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
export default function CreateProfile({ userId }: { userId: any }) {
const router = useRouter();
const [filePP, setFilePP] = useState<File | null>(null);
const [imgPP, setImgPP] = useState<any | null>();
const [fileBG, setFileBG] = useState<File | null>(null);
const [imgBG, setImgBG] = useState<any | null>();
const [value, setValue] = useState({
name: "",
@@ -22,33 +45,108 @@ export default function CreateProfile({ userId }: { userId: any }) {
jenisKelamin: "",
});
async function onSubmit() {
const body = {
userId: userId,
name: value.name,
email: value.email,
alamat: value.alamat,
jenisKelamin: value.jenisKelamin,
};
myConsole(body);
if (_.values(value).includes("")) return toast("Lengkapi data");
// if(_.values(value.email).includes(`${/^\S+@\S+$/.test(value.email) ? null : "Invalid email"}`)){}
await funCreateNewProfile(body).then((res) => {
if (res.status === 201) {
toast("Data tersimpan");
return router.push(`/dev/katalog/${userId}`);
} else {
toast("Gagal")
}
});
}
return (
<>
<Stack px={"sm"}>
<Stack px={"sm"} spacing={"xl"}>
<Box>
<Stack>
<ComponentKatalog_NotedBox informasi="Upload foto profile anda." />
<Center>
<Avatar
sx={{
borderStyle: "solid",
borderColor: "black",
borderWidth: "1px",
}}
src={imgPP ? imgPP : "/aset/global/avatar.png"}
size={150}
radius={"100%"}
/>
</Center>
<Center>
<FileButton
onChange={async (files: any | null) => {
try {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
// console.log(buffer, "ini buffer");
// console.log(files, " ini file");
setImgPP(buffer);
setFilePP(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
variant="outline"
w={150}
leftIcon={<IconCamera />}
compact
>
Upload
</Button>
)}
</FileButton>
</Center>
</Stack>
</Box>
<Box>
<Stack>
<ComponentKatalog_NotedBox informasi="Upload foto latar belakang profile anda." />
<AspectRatio ratio={16 / 9}>
<Paper
radius={"md"}
sx={{
borderStyle: "solid",
borderColor: "black",
borderWidth: "1px",
}}
>
<Image alt="Foto" src={imgBG ? imgBG : "/aset/no-img.png"} />
</Paper>
</AspectRatio>
<Center>
<FileButton
onChange={async (files: any | null) => {
try {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
// console.log(buffer, "ini buffer");
// console.log(files, " ini file");
setImgBG(buffer);
setFileBG(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
variant="outline"
w={150}
leftIcon={<IconCamera />}
compact
>
Upload
</Button>
)}
</FileButton>
</Center>
</Stack>
</Box>
<TextInput
label="Nama"
onChange={(val) => {
@@ -94,7 +192,9 @@ export default function CreateProfile({ userId }: { userId: any }) {
radius={50}
bg={Warna.hijau_muda}
color="green"
onClick={() => onSubmit()}
onClick={() =>
onSubmit(router, value as any, userId, filePP as any, fileBG as any)
}
>
Simpan
</Button>
@@ -102,3 +202,41 @@ export default function CreateProfile({ userId }: { userId: any }) {
</>
);
}
async function onSubmit(
router: AppRouterInstance,
value: MODEL_PROFILE,
userId: string,
filePP: FormData,
fileBg: FormData
) {
const body = {
userId: userId,
name: value.name,
email: value.email,
alamat: value.alamat,
jenisKelamin: value.jenisKelamin,
};
if(_.values(body).includes("")) return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data")
const gambarPP = new FormData();
gambarPP.append("filePP", filePP as any);
const gambarBG = new FormData();
gambarBG.append("fileBG", fileBg as any);
if(!gambarPP) return ComponentGlobal_NotifikasiPeringatan("Lengkapi foto profile")
if(!gambarBG) return ComponentGlobal_NotifikasiPeringatan("Lengkapi background profile")
await funCreateNewProfile(body as any, gambarPP, gambarBG).then((res) => {
if (res.status === 201) {
ComponentGlobal_NotifikasiBerhasil("Berhasil Membuat Profile")
router.push(RouterProfile.katalog + `${userId}`);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}

View File

@@ -10,24 +10,20 @@ import {
} from "@mantine/core";
import { IconArrowLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import ComponentKatalog_HeaderTamplate from "../../component/header_tamplate";
export default function EditProfileLayout({ children, profileId }: { children: any, profileId: any }) {
const router = useRouter()
export default function EditProfileLayout({
children,
profileId,
}: {
children: any;
profileId: any;
}) {
const router = useRouter();
return (
<>
<AppShell
header={
<Header height={50} px={"sm"}>
<Group position="apart" h={50}>
<ActionIcon variant="transparent" onClick={() => router.push(`/dev/katalog/${profileId}`)}>
<IconArrowLeft />
</ActionIcon>
<Text>Edit Profile</Text>
<ActionIcon variant="transparent"></ActionIcon>
</Group>
</Header>
}
header={<ComponentKatalog_HeaderTamplate title="Edit Profile" />}
>
{children}
</AppShell>

View File

@@ -3,7 +3,6 @@
import { myConsole } from "@/app/fun/my_console";
import { ApiHipmi } from "@/app/lib/api";
import { Warna } from "@/app/lib/warna";
import { gs_token } from "@/app_modules/home/state/global_state";
import { Button, Loader, Select, Stack, TextInput } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useAtom } from "jotai";
@@ -11,12 +10,15 @@ import _ from "lodash";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import { gs_profile } from "../state/global_state";
import { loadDataProfile } from "../fun/fun_get_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import funEditProfile from "../fun/fun_edit_profile";
export default function EditProfile({ data }: { data: MODEL_User_profile }) {
import funEditProfile from "../fun/fun_edit_profile";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { MODEL_PROFILE } from "../model/interface";
import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
export default function EditProfile({ data }: { data: MODEL_PROFILE }) {
const router = useRouter();
//Get data profile
@@ -26,12 +28,12 @@ export default function EditProfile({ data }: { data: MODEL_User_profile }) {
const body = dataProfile;
if (_.values(body).includes("")) return toast("Lengkapi data");
await funEditProfile(body).then((res) => {
await Profile_funEditById(body).then((res) => {
if (res.status === 200) {
toast("Update berhasil");
setTimeout(() => router.push(`/dev/katalog/${data.Profile?.id}`), 1000);
ComponentGlobal_NotifikasiBerhasil(res.message);
setTimeout(() => router.back(), 1000)
} else {
toast("Gagal update");
ComponentGlobal_NotifikasiGagal(res.message);
}
});
}
@@ -46,20 +48,21 @@ export default function EditProfile({ data }: { data: MODEL_User_profile }) {
return (
<>
<Stack px={"sm"}>
<TextInput label="Username" disabled value={dataProfile.username} />
<TextInput label="Nomor" disabled value={dataProfile.nomor} />
<TextInput
label="Username"
disabled
value={dataProfile.User.username}
/>
<TextInput label="Nomor" disabled value={dataProfile.User.nomor} />
<TextInput
label="Nama"
placeholder="username"
value={dataProfile.Profile?.name}
placeholder="Nama"
value={dataProfile.name}
onChange={(val) => {
setDataProfile({
...(dataProfile as any),
Profile: {
...dataProfile.Profile,
name: val.target.value,
},
...dataProfile,
name: val.target.value,
});
}}
/>
@@ -67,14 +70,11 @@ export default function EditProfile({ data }: { data: MODEL_User_profile }) {
<TextInput
label="Email"
placeholder="email"
value={dataProfile.Profile?.email}
value={dataProfile.email}
onChange={(val) => {
setDataProfile({
...(dataProfile as any),
Profile: {
...dataProfile.Profile,
email: val.target.value,
},
...dataProfile,
email: val.target.value,
});
}}
/>
@@ -82,32 +82,26 @@ export default function EditProfile({ data }: { data: MODEL_User_profile }) {
<TextInput
label="Alamat"
placeholder="alamat"
value={dataProfile.Profile?.alamat}
value={dataProfile.alamat}
onChange={(val) => {
setDataProfile({
...(dataProfile as any),
Profile: {
...dataProfile.Profile,
alamat: val.target.value,
},
...dataProfile,
alamat: val.target.value,
});
}}
/>
<Select
label="Jenis Kelamin"
value={dataProfile.Profile?.jenisKelamin}
value={dataProfile.jenisKelamin}
data={[
{ value: "Laki-laki", label: "Laki-laki" },
{ value: "Perempuan", label: "Perempuan" },
]}
onChange={(val) => {
onChange={(val: any) => {
setDataProfile({
...(dataProfile as any),
Profile: {
...dataProfile.Profile,
jenisKelamin: val,
},
...dataProfile,
jenisKelamin: val
});
}}
/>

View File

@@ -1,25 +1,88 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PROFILE } from "../model/interface";
import _ from "lodash";
import { v4 } from "uuid";
import fs from "fs";
export default async function funCreateNewProfile(data: any) {
// console.log(data);
const body = data;
export default async function funCreateNewProfile(
req: MODEL_PROFILE,
gambarPP: FormData,
gambarBG: FormData
) {
const body = req;
const res = await prisma.profile.create({
const findEmail = await prisma.profile.findUnique({
where: {
email: body.email,
},
});
if (findEmail) return { status: 400, message: "Email telah digunakan" };
const gambarProfile: any = gambarPP.get("filePP");
const fileName = gambarProfile.name;
const fileExtension = _.lowerCase(gambarProfile.name.split(".").pop());
const fRandomName = v4(fileName) + "." + fileExtension;
const uploadPP = await prisma.images.create({
data: {
url: fRandomName,
label: "PROFILE_FOTO",
},
select: {
id: true,
url: true,
},
});
if (!uploadPP) return { status: 400, message: "Gagal upload foto profile" };
const uploadPP_Folder = Buffer.from(await gambarProfile.arrayBuffer());
fs.writeFileSync(`./public/profile/foto/${uploadPP.url}`, uploadPP_Folder);
const gambarBackground: any = gambarBG.get("fileBG");
const fileNameBG = gambarBackground.name;
const fileExtensionBG = _.lowerCase(gambarBackground.name.split(".").pop());
const fRandomNameBG = v4(fileNameBG) + "." + fileExtensionBG;
const uploadBG = await prisma.imagesBackground.create({
data: {
url: fRandomNameBG,
label: "PROFILE_BACKGROUND",
},
select: {
id: true,
url: true,
},
});
if (!uploadBG)
return { status: 400, message: "Gagal upload background profile" };
const uploadBG_Folder = Buffer.from(await gambarBackground.arrayBuffer());
fs.writeFileSync(
`./public/profile/background/${uploadBG.url}`,
uploadBG_Folder
);
const createProfile = await prisma.profile.create({
data: {
userId: body.userId,
name: body.name,
email: body.email,
alamat: body.alamat,
jenisKelamin: body.jenisKelamin,
imagesId: uploadPP.id,
imagesBackgroundId: uploadBG.id,
},
});
if (!res) return { status: 400 };
if (!createProfile) return { status: 400, message: "Gagal membuat profile" };
return {
status: 201,
success: true,
message: "Berhasil",
};
}

View File

@@ -1,9 +1,17 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { MODEL_PROFILE_OLD } from "@/app_modules/home/model/user_profile";
export default async function funEditProfile(data: MODEL_PROFILE_OLD) {
// const cekEmail = await prisma.profile.findMany({
// where: {
// email: data.Profile.email
// }
// })
// if(cekEmail) return {status: 400, message: "Email sudah di gunakan"}
export default async function funEditProfile(data: MODEL_User_profile) {
const res = await prisma.profile.update({
where: {
id: data.Profile?.id,
@@ -16,10 +24,10 @@ export default async function funEditProfile(data: MODEL_User_profile) {
},
});
if (!res) return { status: 400 };
if (!res) return { status: 400, message: "Gagal update" };
return {
status: 200,
success: true,
message: "Berhasil update",
};
}

View File

@@ -1,15 +0,0 @@
import { myConsole } from "@/app/fun/my_console";
import { getProfile } from "..";
/**
* @function get data profile
* @param setProfile
* @returns data profile
*/
export async function loadDataProfile(setProfile: any) {
await getProfile()
.then((res) => res)
.then((val) => {
setProfile(val);
});
}

View File

@@ -0,0 +1,14 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Profile_getOneById(profileId: string) {
const data = await prisma.profile.findFirst({
where: {
id: profileId,
},
});
return data;
}

View File

@@ -0,0 +1,29 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function Profile_getOneProfileAndUserById(profileId: string) {
const data = await prisma.profile.findFirst({
where: {
id: profileId,
},
select: {
userId: true,
User: true,
id: true,
name: true,
email: true,
alamat: true,
jenisKelamin: true,
imagesId: true,
imagesBackgroundId: true,
ImageProfile: true,
ImagesBackground: true
}
});
// console.log(data)
return data;
}

View File

@@ -0,0 +1,26 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_PROFILE } from "../../model/interface";
import { revalidatePath } from "next/cache";
export async function Profile_funEditById(data: MODEL_PROFILE) {
const updt = await prisma.profile.update({
where: {
id: data.id,
},
data: {
name: data.name,
email: data.email,
alamat: data.alamat,
jenisKelamin: data.jenisKelamin,
},
});
if(!updt) return {status: 400, message: "Gagal update"}
revalidatePath("/dev/katalog")
return {
status: 200,
message: "Berhasil update"
}
}

Some files were not shown because too many files have changed in this diff Show More