fix create sub bidang portofolio
This commit is contained in:
@@ -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 {
|
||||
|
||||
40
src/app/api/master/sub-bidang-bisnis/[id]/route.ts
Normal file
40
src/app/api/master/sub-bidang-bisnis/[id]/route.ts
Normal 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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
33
src/app/api/master/sub-bidang-bisnis/route.ts
Normal file
33
src/app/api/master/sub-bidang-bisnis/route.ts
Normal 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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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") {
|
||||
|
||||
@@ -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(
|
||||
{
|
||||
|
||||
@@ -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/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 }), {
|
||||
|
||||
@@ -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}
|
||||
|
||||
505
src/app_modules/katalog/portofolio/create/new_create.tsx
Normal file
505
src/app_modules/katalog/portofolio/create/new_create.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ export interface IDetailPortofolioBisnis {
|
||||
deskripsi: string
|
||||
logoId: string
|
||||
bidangBisnis: string
|
||||
subBidangBisnis: string[]
|
||||
authorId: string
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface MODEL_PORTOFOLIO_BIDANG_BISNIS {
|
||||
id: string;
|
||||
name: string;
|
||||
active: boolean;
|
||||
slug: string
|
||||
}
|
||||
|
||||
export interface MODEL_PORTOFOLIO_MEDSOS {
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user