fix create sub bidang portofolio

This commit is contained in:
2025-05-08 17:53:50 +08:00
parent def4460f71
commit 96b3dc2674
14 changed files with 769 additions and 24 deletions

View File

@@ -129,11 +129,13 @@ model Portofolio {
updatedAt DateTime @default(now()) @updatedAt
Profile Profile? @relation(fields: [profileId], references: [id])
profileId String?
MasterBidangBisnis MasterBidangBisnis @relation(fields: [masterBidangBisnisId], references: [id])
masterBidangBisnisId String
Portofolio_MediaSosial Portofolio_MediaSosial?
BusinessMaps BusinessMaps?
logoId String?
MasterBidangBisnis MasterBidangBisnis @relation(fields: [masterBidangBisnisId], references: [id])
masterBidangBisnisId String
Portofolio_BidangDanSubBidangBisnis Portofolio_BidangDanSubBidangBisnis[]
}
model Portofolio_MediaSosial {
@@ -152,26 +154,42 @@ model Portofolio_MediaSosial {
// ------------------- MASTER -------------------------- //
model Portofolio_BidangDanSubBidangBisnis {
id String @id @default(cuid())
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Portofolio Portofolio? @relation(fields: [portofolioId], references: [id])
portofolioId String?
MasterBidangBisnis MasterBidangBisnis? @relation(fields: [masterBidangBisnisId], references: [id])
masterBidangBisnisId String?
MasterSubBidangBisnis MasterSubBidangBisnis? @relation(fields: [masterSubBidangBisnisId], references: [id])
masterSubBidangBisnisId String?
}
model MasterBidangBisnis {
id String @id @default(uuid())
name String
slug String @unique @default("NULL")
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
Portofolio Portofolio[]
MasterSubBidangBisnis MasterSubBidangBisnis[]
id String @id @default(uuid())
name String
slug String @unique @default("NULL")
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
Portofolio Portofolio[]
MasterSubBidangBisnis MasterSubBidangBisnis[]
Portofolio_BidangDanSubBidangBisnis Portofolio_BidangDanSubBidangBisnis[]
}
model MasterSubBidangBisnis {
id String @id @default(cuid())
name String
slug String @unique @default("NULL")
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
MasterBidangBisnis MasterBidangBisnis? @relation(fields: [masterBidangBisnisId], references: [id])
masterBidangBisnisId String?
id String @id @default(cuid())
name String
slug String @unique @default("NULL")
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
MasterBidangBisnis MasterBidangBisnis? @relation(fields: [masterBidangBisnisId], references: [id])
masterBidangBisnisId String?
Portofolio_BidangDanSubBidangBisnis Portofolio_BidangDanSubBidangBisnis[]
}
model MasterBank {

View File

@@ -0,0 +1,40 @@
import { prisma } from "@/lib";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
try {
let fixData;
const { id } = params;
fixData = await prisma.masterSubBidangBisnis.findMany({
where: {
masterBidangBisnisId: id.toString(),
isActive: true,
},
});
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan data",
data: fixData,
},
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error Get Master Sub Bidang Bisnis >>", error);
return NextResponse.json(
{
success: false,
message: "API Error Get Data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,33 @@
import { prisma } from "@/lib";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
let fixData;
fixData = await prisma.masterSubBidangBisnis.findMany({
where: {
isActive: true,
},
});
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan data",
data: fixData,
},
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error Get Master Sub Bidang Bisnis >>", error);
return NextResponse.json(
{
success: false,
message: "API Error Get Data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -36,6 +36,15 @@ export async function GET(
userId: true,
},
},
Portofolio_BidangDanSubBidangBisnis: {
select: {
MasterSubBidangBisnis: {
select: {
name: true,
},
},
},
},
},
});
@@ -47,6 +56,7 @@ export async function GET(
deskripsi: data?.deskripsi,
logoId: data?.logoId,
bidangBisnis: data?.MasterBidangBisnis?.name,
subBidangBisnis: data?.Portofolio_BidangDanSubBidangBisnis?.map((item) => item.MasterSubBidangBisnis?.name),
authorId: data?.Profile?.userId,
};
} else if (kategori == "lokasi") {

View File

@@ -155,6 +155,28 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
},
});
for (let i of data.subBidang) {
// console.log("sub bidang", i.id)
const createSubBidang =
await prisma.portofolio_BidangDanSubBidangBisnis.create({
data: {
portofolioId: createPortofolio.id,
masterBidangBisnisId: data.masterBidangBisnisId,
masterSubBidangBisnisId: i.id,
},
});
if (!createSubBidang)
return NextResponse.json(
{
success: false,
message: "Gagal membuat sub bidang bisnis",
},
{ status: 400 }
);
}
if (!createPortofolio)
return NextResponse.json(
{

View File

@@ -1,9 +1,11 @@
import { CreatePortofolio } from "@/app_modules/katalog/portofolio";
import Portofolio_V3_Create from "@/app_modules/katalog/portofolio/create/new_create";
export default async function Page() {
return (
<>
<CreatePortofolio />
{/* <CreatePortofolio /> */}
<Portofolio_V3_Create/>
</>
);
}

View File

@@ -3,22 +3,24 @@
import { APIs } from "@/lib";
import { pathAssetImage } from "@/lib/path_asset_image";
import { RouterImagePreview } from "@/lib/router_hipmi/router_image_preview";
import { Center, Image, Skeleton } from "@mantine/core";
import { Center, Image, MantineNumberSize, Skeleton } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useState } from "react";
type IRadius = "xs" | "sm" | "md" | "lg" | "xl";
type IRadius = MantineNumberSize | undefined
export function ComponentGlobal_LoadImage({
fileId,
maw,
h,
radius,
style,
}: {
fileId: string;
maw?: number | string;
h?: number;
radius?: IRadius;
style?: React.CSSProperties;
}) {
const router = useRouter();
const [isImage, setIsImage] = useState<boolean | null>(null);
@@ -44,7 +46,7 @@ export function ComponentGlobal_LoadImage({
if (isImage === null)
return (
<Center h={"100%"}>
<Skeleton h={250} radius={"sm"} w={250} />
</Center>
@@ -63,6 +65,9 @@ export function ComponentGlobal_LoadImage({
<>
<Center h={"100%"}>
<Image
style={{
...style
}}
onClick={() => {
setIsLoading(true);
router.push(RouterImagePreview.main({ id: fileId }), {

View File

@@ -16,6 +16,10 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import { apiCreatePortofolio } from "../api_fetch_portofolio";
type SubBidang = {
id: string;
};
interface ICreatePortofolio {
namaBisnis: string;
masterBidangBisnisId: string;
@@ -28,18 +32,23 @@ interface ICreatePortofolio {
instagram: string;
tiktok: string;
youtube: string;
subBidang: SubBidang[];
}
export function Portofolio_ComponentButtonSelanjutnya({
profileId,
dataPortofolio,
dataMedsos,
file,
listSubBidangSelected,
}: {
profileId: string;
dataPortofolio: MODEL_PORTOFOLIO_OLD;
dataMedsos: any;
file: File;
listSubBidangSelected?: SubBidang[];
}) {
const router = useRouter();
const [loading, setLoading] = useState(false);
@@ -62,6 +71,7 @@ export function Portofolio_ComponentButtonSelanjutnya({
const newData: ICreatePortofolio = {
namaBisnis: dataPortofolio.namaBisnis,
masterBidangBisnisId: dataPortofolio.masterBidangBisnisId,
// masterSubBidangBisnisId: dataPortofolio.masterSubBidangBisnisId as string,
alamatKantor: dataPortofolio.alamatKantor,
tlpn: dataPortofolio.tlpn,
deskripsi: dataPortofolio.deskripsi,
@@ -71,6 +81,7 @@ export function Portofolio_ComponentButtonSelanjutnya({
tiktok: dataMedsos.tiktok,
youtube: dataMedsos.youtube,
fileId: fileId,
subBidang: listSubBidangSelected || []
};
const response = await apiCreatePortofolio({
@@ -91,8 +102,10 @@ export function Portofolio_ComponentButtonSelanjutnya({
if (!validateData()) return;
try {
console.log("listSubBidangSelected>>", listSubBidangSelected);
setLoading(true);
const uploadFile = await funGlobal_UploadToStorage({
file: file,
dirId: DIRECTORY_ID.portofolio_logo,
@@ -107,14 +120,25 @@ export function Portofolio_ComponentButtonSelanjutnya({
} catch (error) {
setLoading(false);
ComponentGlobal_NotifikasiGagal("Gagal disimpan");
clientLogger.error("Error create portofolio", error);
console.error("Error create portofolio", error);
}
};
return (
<>
{/* <pre style={{ color: "white" }}>
{JSON.stringify(dataPortofolio, null, 2)}
</pre>
<pre style={{ color: "white" }}>
{JSON.stringify(listSubBidangSelected, null, 2)}
</pre> */}
<Button
disabled={_.values(dataPortofolio).includes("") || !file}
disabled={
_.values(dataPortofolio).includes("") ||
!file ||
listSubBidangSelected?.some((item) => !item.id)
}
mt={"md"}
radius={50}
loading={loading}

View File

@@ -0,0 +1,505 @@
"use client";
import { MainColor } from "@/app_modules/_global/color/color_pallet";
import {
ComponentGlobal_BoxUploadImage,
ComponentGlobal_ButtonUploadFileImage,
} from "@/app_modules/_global/component";
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown";
import { apiGetMasterBidangBisnis } from "@/app_modules/_global/lib/api_fetch_master";
import { ISUB_BIDANG_BISNIS } from "@/app_modules/model_global/portofolio";
import { clientLogger } from "@/util/clientLogger";
import {
AspectRatio,
Box,
Button,
Center,
Group,
Image,
Select,
Stack,
Styles,
Text,
TextInput,
Textarea,
} from "@mantine/core";
import { BaseSelectStylesNames } from "@mantine/core/lib/Select/types";
import { useShallowEffect } from "@mantine/hooks";
import { IconMinus, IconPhoto, IconPlus } from "@tabler/icons-react";
import _ from "lodash";
import { useParams } from "next/navigation";
import { useState } from "react";
import { PhoneInput } from "react-international-phone";
import "react-international-phone/style.css";
import { Portofolio_ComponentButtonSelanjutnya } from "../component";
import { apiGetSubBidangBisnis } from "../lib/api_portofolio";
import { MODEL_PORTOFOLIO_BIDANG_BISNIS } from "../model/interface";
export default function Portofolio_V3_Create() {
const params = useParams<{ id: string }>();
const profileId = params.id;
const [dataPortofolio, setDataPortofolio] = useState({
namaBisnis: "",
masterBidangBisnisId: "",
// masterSubBidangBisnisId: "",
alamatKantor: "",
tlpn: "",
deskripsi: "",
});
const [dataMedsos, setDataMedsos] = useState({
facebook: "",
twitter: "",
instagram: "",
youtube: "",
tiktok: "",
});
const [file, setFile] = useState<File | null>(null);
const [img, setImg] = useState<any | null>(null);
const [listBidangBisnis, setListBidangBisnis] = useState<
MODEL_PORTOFOLIO_BIDANG_BISNIS[] | null
>(null);
const [listSubBidang, setListSubBidang] = useState<
ISUB_BIDANG_BISNIS[] | null
>(null);
const [selectedSubBidang, setSelectedSubBidang] = useState<
ISUB_BIDANG_BISNIS[] | null
>(null);
const [listSubBidangSelected, setListSubBidangSelected] = useState([
{
id: "",
},
]);
useShallowEffect(() => {
onLoadMasterBidangBisnis();
onLoadMasterSubBidangBisnis();
}, []);
async function onLoadMasterBidangBisnis() {
try {
const respone = await apiGetMasterBidangBisnis();
if (respone.success) {
setListBidangBisnis(respone.data);
}
} catch (error) {
clientLogger.error("Error on load master bidang bisnis", error);
}
}
async function onLoadMasterSubBidangBisnis() {
try {
const response = await apiGetSubBidangBisnis({});
if (response.success) {
setListSubBidang(response.data);
}
} catch (error) {
clientLogger.error("Error on load master sub bidang bisnis", error);
}
}
const handlerSelectedSubBidang = ({ id }: { id: string }) => {
const selectedList = listSubBidang?.filter(
(item) => item.masterBidangBisnisId === id
);
setSelectedSubBidang(selectedList as ISUB_BIDANG_BISNIS[]);
};
const baseStyles: Styles<BaseSelectStylesNames, Record<string, any>> = {
label: {
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
};
return (
<>
<Stack px={"sm"} mb={"lg"} spacing={50}>
<Stack spacing={"sm"}>
<ComponentGlobal_BoxInformation informasi="Lengkapi data bisnis" />
<TextInput
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
}}
withAsterisk
label="Nama Bisnis"
placeholder="Nama bisnis"
maxLength={100}
onChange={(val) => {
setDataPortofolio({
...dataPortofolio,
namaBisnis: _.startCase(val.target.value),
});
}}
/>
<Select
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
dropdown: {
backgroundColor: MainColor.white,
},
}}
withAsterisk
label="Bidang Bisnis"
placeholder={
listBidangBisnis ? "Pilih bidang bisnis" : "Loading..."
}
data={_.map(listBidangBisnis as any).map((e: any) => ({
value: e.id,
label: e.name,
}))}
onChange={(val: any) => {
const isSameBidang = dataPortofolio.masterBidangBisnisId === val;
// Update data portofolio
setDataPortofolio({
...dataPortofolio,
masterBidangBisnisId: val,
// masterSubBidangBisnisId: isSameBidang
// ? dataPortofolio.masterSubBidangBisnisId
// : "",
});
// Jika berbeda bidang, reset sub bidang ke satu input kosong
if (!isSameBidang) {
setListSubBidangSelected([{ id: "" }]);
}
// Panggil handler sub bidang berdasarkan bidang bisnis terpilih
handlerSelectedSubBidang({ id: val });
}}
/>
<Stack>
{listSubBidangSelected.map((e, index) => (
<Box key={index}>
<Select
disabled={dataPortofolio.masterBidangBisnisId === ""}
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
dropdown: {
backgroundColor: MainColor.white,
},
}}
withAsterisk
label={`Sub Bidang Bisnis ${index + 1}`}
placeholder={
selectedSubBidang
? "Pilih sub bidang bisnis"
: "Menunggu pilihan bidang bisnis"
}
data={_.map(selectedSubBidang as any)
.filter((option: any) => {
const selectedValues = listSubBidangSelected.map(
(s) => s.id
);
return (
option.id === e.id || // biarkan tetap muncul kalau ini valuenya sendiri
!selectedValues.includes(option.id)
);
})
.map((e: any) => ({
value: e.id,
label: e.name,
}))}
value={e.id}
onChange={(val) => {
const list = _.clone(listSubBidangSelected);
list[index].id = val as any;
setListSubBidangSelected(list);
}}
error={
listSubBidangSelected.length > 1 && !e.id
? "Wajib dipilih / kurangi list"
: undefined
}
/>
</Box>
))}
</Stack>
<Group position="center">
<Button
disabled={
listSubBidangSelected.length === selectedSubBidang?.length
}
radius="xl"
leftIcon={<IconPlus size={15} />}
onClick={() => {
setListSubBidangSelected([
...listSubBidangSelected,
{ id: "" },
]);
}}
compact
bg={MainColor.yellow}
color="yellow"
c="black"
>
<Text fz={8}>Tambah List</Text>
</Button>
<Button
disabled={listSubBidangSelected.length <= 1}
radius="xl"
leftIcon={<IconMinus size={15} />}
onClick={() => {
setListSubBidangSelected(listSubBidangSelected.slice(0, -1));
}}
compact
bg={MainColor.yellow}
color="yellow"
c="black"
>
<Text fz={8}>Kurangi List</Text>
</Button>
</Group>
{/* <pre style={{ color: "white" }}>
{JSON.stringify(dataPortofolio, null, 2)}
</pre>
<pre style={{ color: "white" }}>
{JSON.stringify(listSubBidangSelected, null, 2)}
</pre> */}
{/* <Select
disabled={dataPortofolio.masterBidangBisnisId == ""}
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
dropdown: {
backgroundColor: MainColor.white,
},
}}
value={dataPortofolio.masterSubBidangBisnisId == ""
? null
: dataPortofolio.masterSubBidangBisnisId
}
withAsterisk
label="Sub Bidang Bisnis"
placeholder={
selectedSubBidang ? "Pilih sub bidang bisnis" : "Menunggu pilihan bidang bisnis"
}
data={_.map(selectedSubBidang as any).map((e: any) => ({
value: e.id,
label: e.name,
}))}
onChange={(val) => {
setDataPortofolio({
...dataPortofolio,
masterSubBidangBisnisId: val as any,
});
}}
/> */}
<TextInput
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
}}
withAsterisk
label="Alamat Bisnis"
placeholder="Alamat bisnis"
maxLength={100}
onChange={(val) => {
setDataPortofolio({
...dataPortofolio,
alamatKantor: val.target.value,
});
}}
/>
<Stack spacing={5}>
<Text c={MainColor.white} fz={"sm"}>
Nomor Telepon{" "}
<Text c={"red"} span inherit>
*
</Text>
</Text>
<PhoneInput
placeholder="Nomor telepon"
countrySelectorStyleProps={{
buttonStyle: {
backgroundColor: MainColor.login,
},
}}
inputStyle={{ width: "100%", backgroundColor: MainColor.white }}
defaultCountry="id"
onChange={(val) => {
const valPhone = val.substring(1);
setDataPortofolio({
...dataPortofolio,
tlpn: valPhone,
});
}}
/>
</Stack>
<Stack spacing={5}>
<Textarea
styles={{
...baseStyles,
required: {
color: MainColor.red,
},
}}
maxLength={300}
autosize
minRows={2}
maxRows={5}
withAsterisk
label="Deskripsi"
placeholder="Deskripsi singkat mengenai usaha"
onChange={(val) => {
setDataPortofolio({
...dataPortofolio,
deskripsi: val.target.value,
});
}}
/>
<ComponentGlobal_InputCountDown
maxInput={300}
lengthInput={dataPortofolio.deskripsi.length}
/>
</Stack>
</Stack>
<Stack>
<ComponentGlobal_BoxInformation informasi="Upload logo bisnis anda untuk ditampilkan dalam portofolio " />
<ComponentGlobal_BoxUploadImage>
{img ? (
<AspectRatio ratio={1 / 1} mah={265} mx={"auto"}>
<Image
style={{ maxHeight: 250, margin: "auto", padding: "5px" }}
alt="Foto"
height={250}
src={img}
/>
</AspectRatio>
) : (
<Stack spacing={5} justify="center" align="center" h={"100%"}>
<IconPhoto size={100} />
</Stack>
)}
</ComponentGlobal_BoxUploadImage>
<Center>
<ComponentGlobal_ButtonUploadFileImage
onSetFile={setFile}
onSetImage={setImg}
/>
</Center>
</Stack>
<Stack>
<ComponentGlobal_BoxInformation informasi="Isi hanya pada sosial media yang anda miliki" />
<TextInput
styles={{
...baseStyles,
}}
label="Facebook"
maxLength={100}
placeholder="Facebook"
onChange={(val) => {
setDataMedsos({
...dataMedsos,
facebook: val.target.value,
});
}}
/>
<TextInput
styles={{
...baseStyles,
}}
label="Instagram"
maxLength={100}
placeholder="Instagram"
onChange={(val) => {
setDataMedsos({
...dataMedsos,
instagram: val.target.value,
});
}}
/>
<TextInput
styles={{
...baseStyles,
}}
label="Tiktok"
maxLength={100}
placeholder="Tiktok"
onChange={(val) => {
setDataMedsos({
...dataMedsos,
tiktok: val.target.value,
});
}}
/>
<TextInput
styles={{
...baseStyles,
}}
label="Twitter"
maxLength={100}
placeholder="Twitter"
onChange={(val) => {
setDataMedsos({
...dataMedsos,
twitter: val.target.value,
});
}}
/>
<TextInput
styles={{
...baseStyles,
}}
label="Youtube"
maxLength={100}
placeholder="Youtube"
onChange={(val) => {
setDataMedsos({
...dataMedsos,
youtube: val.target.value,
});
}}
/>
</Stack>
<Portofolio_ComponentButtonSelanjutnya
dataPortofolio={dataPortofolio as any}
listSubBidangSelected={listSubBidangSelected as any}
dataMedsos={dataMedsos}
profileId={profileId}
//
file={file as File}
/>
</Stack>
</>
);
}

View File

@@ -48,3 +48,46 @@ export const apiDeletePortofolio = async (path: string) => {
return await response.json().catch(() => null);
};
export const apiGetSubBidangBisnis = async ({id}: {id?: string}) => {
try {
// Fetch token from cookie
const { token } = await fetch("/api/get-cookie").then((res) =>
res.json()
);
if (!token) {
console.error("No token found");
return null;
}
const bidangBisnisId = id ? `/${id}` : "";
const response = await fetch(`/api/master/sub-bidang-bisnis${bidangBisnisId}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${token}`,
},
});
// Check if the response is OK
if (!response.ok) {
const errorData = await response.json().catch(() => null);
console.error(
"Failed to get all forum:",
response.statusText,
errorData
);
throw new Error(errorData?.message || "Failed to get all forum");
}
// Return the JSON response
const result = await response.json();
return result;
} catch (error) {
console.error("Error get all forum", error);
throw error; // Re-throw the error to handle it in the calling function
}
}

View File

@@ -13,6 +13,7 @@ export interface IDetailPortofolioBisnis {
deskripsi: string
logoId: string
bidangBisnis: string
subBidangBisnis: string[]
authorId: string
}

View File

@@ -34,6 +34,7 @@ export interface MODEL_PORTOFOLIO_BIDANG_BISNIS {
id: string;
name: string;
active: boolean;
slug: string
}
export interface MODEL_PORTOFOLIO_MEDSOS {

View File

@@ -15,6 +15,7 @@ import {
import { useShallowEffect } from "@mantine/hooks";
import {
IconBuildingSkyscraper,
IconCaretRightFilled,
IconListDetails,
IconMapPin,
IconPhoneCall,
@@ -39,6 +40,7 @@ export default function Portofolio_UiDetailDataNew() {
setLoading(true);
const response = await apiGetOnePortofolioById(param.id, "bisnis");
if (response) {
console.log(response.data);
setDataPorto(response.data);
}
} catch (error) {
@@ -104,6 +106,7 @@ export default function Portofolio_UiDetailDataNew() {
<Text>{dataPorto?.namaBisnis}</Text>
</Grid.Col>
</Grid>
<Grid>
<Grid.Col span={2}>
<IconListDetails />
@@ -112,6 +115,25 @@ export default function Portofolio_UiDetailDataNew() {
<Text>{dataPorto?.bidangBisnis}</Text>
</Grid.Col>
</Grid>
{dataPorto?.subBidangBisnis.map((item, index) => (
<Grid key={index} ml={2}>
<Grid.Col span={2}>
<IconCaretRightFilled />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{item}</Text>
</Grid.Col>
</Grid>
))}
{/* <Grid>
<Grid.Col span={2}>
<IconListDetails />
</Grid.Col>
<Grid.Col span={"auto"}>
<Text>{dataPorto?.subBidangBisnis}</Text>
</Grid.Col>
</Grid> */}
<Grid>
<Grid.Col span={2}>
<IconPhoneCall />

View File

@@ -1,3 +1,5 @@
import { Prisma } from "@prisma/client";
export interface MODEL_PORTOFOLIO_Lama {
id: string;
namaBisnis: string;
@@ -15,6 +17,21 @@ export interface BIDANG_BISNIS_OLD {
active: boolean;
}
export interface MODAL_SUB_BIDANG_BISNIS {
id: string;
name: string;
isActive: boolean;
}
export type ISUB_BIDANG_BISNIS = Prisma.MasterSubBidangBisnisGetPayload<{
select: {
id: true;
name: true;
isActive: true;
masterBidangBisnisId: true;
};
}>;
export interface MODEL_PORTOFOLIO_OLD {
id: string;
namaBisnis: string;
@@ -24,5 +41,7 @@ export interface MODEL_PORTOFOLIO_OLD {
active: boolean;
MasterBidangBisnis: BIDANG_BISNIS_OLD;
masterBidangBisnisId: string
MasterSubBidangBisnis: MODAL_SUB_BIDANG_BISNIS;
masterSubBidangBisnisId?: string
profileId: string,
}