API/UI Admin Ekonomi Lowongan kerja
This commit is contained in:
@@ -1075,3 +1075,19 @@ model KategoriMakanan {
|
|||||||
isActive Boolean @default(true)
|
isActive Boolean @default(true)
|
||||||
PasarDesa PasarDesa[]
|
PasarDesa PasarDesa[]
|
||||||
}
|
}
|
||||||
|
// ========================================= LOWONGAN KERJA LOKAL ========================================= //
|
||||||
|
model LowonganPekerjaan {
|
||||||
|
id String @id @default(uuid()) // ID unik untuk setiap lowongan
|
||||||
|
posisi String // Contoh: "Kasir"
|
||||||
|
namaPerusahaan String // Contoh: "Toko Sumber Rejeki"
|
||||||
|
lokasi String // Contoh: "Desa Munggu , Badung"
|
||||||
|
tipePekerjaan String // Contoh: "Full Time", "Part Time", "Contract"
|
||||||
|
gaji String // Contoh: "Rp. 2.500.000 / bulan". Menggunakan String karena formatnya bisa bervariasi
|
||||||
|
deskripsi String // Opsional: Detail deskripsi pekerjaan (tidak terlihat di UI ini, tapi umum ada)
|
||||||
|
kualifikasi String // Opsional: Kualifikasi yang dibutuhkan (tidak terlihat di UI ini, tapi umum ada)
|
||||||
|
tanggalPosting DateTime @default(now()) // Tanggal lowongan diposting
|
||||||
|
isActive Boolean @default(true) // Menandakan apakah lowongan masih aktif
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
deletedAt DateTime @default(now())
|
||||||
|
}
|
||||||
|
|||||||
225
src/app/admin/(dashboard)/_state/ekonomi/lowongan-kerja.ts
Normal file
225
src/app/admin/(dashboard)/_state/ekonomi/lowongan-kerja.ts
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import { proxy } from "valtio";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const templateForm = z.object({
|
||||||
|
posisi: z.string(),
|
||||||
|
namaPerusahaan: z.string(),
|
||||||
|
lokasi: z.string(),
|
||||||
|
tipePekerjaan: z.string(),
|
||||||
|
gaji: z.string(),
|
||||||
|
deskripsi: z.string(),
|
||||||
|
kualifikasi: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultForm = {
|
||||||
|
posisi: "",
|
||||||
|
namaPerusahaan: "",
|
||||||
|
lokasi: "",
|
||||||
|
tipePekerjaan: "",
|
||||||
|
gaji: "",
|
||||||
|
deskripsi: "",
|
||||||
|
kualifikasi: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const lowonganKerjaState = proxy({
|
||||||
|
create: {
|
||||||
|
form: { ...defaultForm },
|
||||||
|
loading: false,
|
||||||
|
async create() {
|
||||||
|
const cek = templateForm.safeParse(lowonganKerjaState.create.form);
|
||||||
|
if (!cek.success) {
|
||||||
|
const err = `[${cek.error.issues
|
||||||
|
.map((v) => `${v.path.join(".")}`)
|
||||||
|
.join("\n")}] required`;
|
||||||
|
return toast.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
lowonganKerjaState.create.loading = true;
|
||||||
|
const res = await ApiFetch.api.ekonomi.lowongankerja["create"].post(
|
||||||
|
lowonganKerjaState.create.form
|
||||||
|
);
|
||||||
|
if (res.status === 200) {
|
||||||
|
lowonganKerjaState.create.loading = false;
|
||||||
|
return toast.success("success create");
|
||||||
|
}
|
||||||
|
console.log(res);
|
||||||
|
return toast.error("failed create");
|
||||||
|
} catch (error) {
|
||||||
|
console.log((error as Error).message);
|
||||||
|
} finally {
|
||||||
|
lowonganKerjaState.create.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
lowonganKerjaState.create.form = { ...defaultForm };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
findMany: {
|
||||||
|
data: null as
|
||||||
|
| Prisma.LowonganPekerjaanGetPayload<{
|
||||||
|
omit: { isActive: true };
|
||||||
|
}>[]
|
||||||
|
| null,
|
||||||
|
async load() {
|
||||||
|
const res = await ApiFetch.api.ekonomi.lowongankerja["find-many"].get();
|
||||||
|
if (res.status === 200) {
|
||||||
|
lowonganKerjaState.findMany.data = res.data?.data ?? [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
findUnique: {
|
||||||
|
data: null as Prisma.LowonganPekerjaanGetPayload<{
|
||||||
|
omit: { isActive: true };
|
||||||
|
}> | null,
|
||||||
|
async load(id: string) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/ekonomi/lowongankerja/${id}`);
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
lowonganKerjaState.findUnique.data = data.data ?? null;
|
||||||
|
} else {
|
||||||
|
console.error("Failed to fetch data", res.status, res.statusText);
|
||||||
|
lowonganKerjaState.findUnique.data = null;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
lowonganKerjaState.findUnique.data = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
loading: false,
|
||||||
|
async byId(id: string) {
|
||||||
|
if (!id) return toast.warn("ID tidak valid");
|
||||||
|
|
||||||
|
try {
|
||||||
|
lowonganKerjaState.delete.loading = true;
|
||||||
|
const response = await fetch(`/api/ekonomi/lowongankerja/del/${id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (response.ok && result?.success) {
|
||||||
|
toast.success(result.message || "Lowongan kerja berhasil dihapus");
|
||||||
|
await lowonganKerjaState.findMany.load(); // refresh list
|
||||||
|
} else {
|
||||||
|
toast.error(result?.message || "Gagal menghapus lowongan kerja");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting data:", error);
|
||||||
|
toast.error("Terjadi kesalahan saat menghapus lowongan kerja");
|
||||||
|
} finally {
|
||||||
|
lowonganKerjaState.delete.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
id: "",
|
||||||
|
form: { ...defaultForm },
|
||||||
|
loading: false,
|
||||||
|
|
||||||
|
async load(id: string) {
|
||||||
|
if (!id) {
|
||||||
|
toast.warn("ID tidak valid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/ekonomi/lowongankerja/${id}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
const result = await response.json();
|
||||||
|
if (result?.success) {
|
||||||
|
const data = result.data;
|
||||||
|
this.id = data.id;
|
||||||
|
this.form = {
|
||||||
|
posisi: data.posisi,
|
||||||
|
namaPerusahaan: data.namaPerusahaan,
|
||||||
|
lokasi: data.lokasi,
|
||||||
|
tipePekerjaan: data.tipePekerjaan,
|
||||||
|
gaji: data.gaji,
|
||||||
|
deskripsi: data.deskripsi,
|
||||||
|
kualifikasi: data.kualifikasi,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
result?.message || "Gagal memuat data lowongan kerja"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
toast.error(
|
||||||
|
error instanceof Error ? error.message : "Gagal memuat data"
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async update() {
|
||||||
|
const cek = templateForm.safeParse(lowonganKerjaState.update.form);
|
||||||
|
if (!cek.success) {
|
||||||
|
const err = `[${cek.error.issues
|
||||||
|
.map((v) => `${v.path.join(".")}`)
|
||||||
|
.join("\n")}] required`;
|
||||||
|
return toast.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
lowonganKerjaState.update.loading = true;
|
||||||
|
const response = await fetch(`/api/ekonomi/lowongankerja/${this.id}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
posisi: this.form.posisi,
|
||||||
|
namaPerusahaan: this.form.namaPerusahaan,
|
||||||
|
lokasi: this.form.lokasi,
|
||||||
|
tipePekerjaan: this.form.tipePekerjaan,
|
||||||
|
gaji: this.form.gaji,
|
||||||
|
deskripsi: this.form.deskripsi,
|
||||||
|
kualifikasi: this.form.kualifikasi,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
throw new Error(
|
||||||
|
errorData.message || `HTTP error! status: ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success) {
|
||||||
|
toast.success("Berhasil update lowongan kerja");
|
||||||
|
await lowonganKerjaState.findMany.load(); // refresh list
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(result.message || "Gagal update lowongan kerja");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating data:", error);
|
||||||
|
toast.error(error instanceof Error ? error.message : "Terjadi kesalahan saat mengupdate lowongan kerja");
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
lowonganKerjaState.update.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
lowonganKerjaState.update.id = "";
|
||||||
|
lowonganKerjaState.update.form = { ...defaultForm };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default lowonganKerjaState;
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
'use client'
|
||||||
|
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||||
|
import lowonganKerjaState from '@/app/admin/(dashboard)/_state/ekonomi/lowongan-kerja';
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||||
|
import { IconArrowBack } from '@tabler/icons-react';
|
||||||
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
|
||||||
|
|
||||||
|
function EditLowonganKerja() {
|
||||||
|
const lowonganState = useProxy(lowonganKerjaState)
|
||||||
|
const router = useRouter();
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
posisi: lowonganKerjaState.update.form.posisi,
|
||||||
|
namaPerusahaan: lowonganKerjaState.update.form.namaPerusahaan,
|
||||||
|
lokasi: lowonganKerjaState.update.form.lokasi,
|
||||||
|
tipePekerjaan: lowonganKerjaState.update.form.tipePekerjaan,
|
||||||
|
gaji: lowonganKerjaState.update.form.gaji,
|
||||||
|
deskripsi: lowonganKerjaState.update.form.deskripsi,
|
||||||
|
kualifikasi: lowonganKerjaState.update.form.kualifikasi,
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadLowongan = async () => {
|
||||||
|
const id = params?.id as string;
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await lowonganState.update.load(id); // akses langsung, bukan dari proxy
|
||||||
|
if (data) {
|
||||||
|
setFormData({
|
||||||
|
posisi: data.posisi || '',
|
||||||
|
namaPerusahaan: data.namaPerusahaan || '',
|
||||||
|
lokasi: data.lokasi || '',
|
||||||
|
tipePekerjaan: data.tipePekerjaan || '',
|
||||||
|
gaji: data.gaji || '',
|
||||||
|
deskripsi: data.deskripsi || '',
|
||||||
|
kualifikasi: data.kualifikasi || '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error loading lowongan kerja:", error);
|
||||||
|
toast.error("Gagal memuat data lowongan kerja");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadLowongan();
|
||||||
|
}, [params?.id])
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
lowonganKerjaState.update.form = {
|
||||||
|
...lowonganKerjaState.update.form,
|
||||||
|
posisi: formData.posisi,
|
||||||
|
namaPerusahaan: formData.namaPerusahaan,
|
||||||
|
lokasi: formData.lokasi,
|
||||||
|
tipePekerjaan: formData.tipePekerjaan,
|
||||||
|
gaji: formData.gaji,
|
||||||
|
deskripsi: formData.deskripsi,
|
||||||
|
kualifikasi: formData.kualifikasi,
|
||||||
|
}
|
||||||
|
await lowonganState.update.update()
|
||||||
|
toast.success("Lowongan kerja berhasil diperbarui!");
|
||||||
|
router.push("/admin/ekonomi/lowongan-kerja-lokal");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating lowongan kerja:", error);
|
||||||
|
toast.error("Terjadi kesalahan saat memperbarui lowongan kerja");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Box mb={10}>
|
||||||
|
<Button onClick={() => router.back()} variant='subtle' color={'blue'}>
|
||||||
|
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Paper w={{ base: '100%', md: '50%' }} bg={colors['white-1']} p={'md'}>
|
||||||
|
<Stack gap={"xs"}>
|
||||||
|
<Title order={4}>Edit Lowongan Kerja Lokal</Title>
|
||||||
|
<TextInput
|
||||||
|
value={formData.posisi}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.posisi = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Posisi</Text>}
|
||||||
|
placeholder='Masukkan posisi'
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
value={formData.namaPerusahaan}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.namaPerusahaan = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Nama Perusahaan</Text>}
|
||||||
|
placeholder='Masukkan nama perusahaan'
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
value={formData.lokasi}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.lokasi = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Lokasi</Text>}
|
||||||
|
placeholder='Masukkan lokasi'
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
value={formData.tipePekerjaan}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.tipePekerjaan = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Tipe Pekerjaan</Text>}
|
||||||
|
placeholder='Masukkan tipe pekerjaan'
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
value={formData.gaji}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.gaji = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
||||||
|
placeholder='Masukkan gaji'
|
||||||
|
/>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"sm"}>Deskripsi Lowongan Kerja</Text>
|
||||||
|
<EditEditor
|
||||||
|
value={formData.deskripsi}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.deskripsi = val;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"sm"}>Kualifikasi Lowongan Kerja</Text>
|
||||||
|
<EditEditor
|
||||||
|
value={formData.kualifikasi}
|
||||||
|
onChange={(val) => {
|
||||||
|
formData.kualifikasi = val;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Group>
|
||||||
|
<Button onClick={handleSubmit} bg={colors['blue-button']}>Submit</Button>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditLowonganKerja;
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
'use client'
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
|
||||||
|
import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
|
||||||
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||||
|
import lowonganKerjaState from '../../../_state/ekonomi/lowongan-kerja';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function DetailLowonganKerjaLokal() {
|
||||||
|
const lowonganState = useProxy(lowonganKerjaState)
|
||||||
|
const [modalHapus, setModalHapus] = useState(false)
|
||||||
|
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||||
|
const params = useParams()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
lowonganState.findUnique.load(params?.id as string)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
const handleHapus = () => {
|
||||||
|
if (selectedId) {
|
||||||
|
lowonganState.delete.byId(selectedId)
|
||||||
|
setModalHapus(false)
|
||||||
|
setSelectedId(null)
|
||||||
|
router.push("/admin/ekonomi/lowongan-kerja-lokal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lowonganState.findUnique.data) {
|
||||||
|
return (
|
||||||
|
<Stack py={10}>
|
||||||
|
<Skeleton h={40} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Box mb={10}>
|
||||||
|
<Button variant="subtle" onClick={() => router.back()}>
|
||||||
|
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
<Paper bg={colors['white-1']} w={{ base: "100%", md: "100%", lg: "50%" }} p={'md'}>
|
||||||
|
<Stack>
|
||||||
|
<Text fz={"xl"} fw={"bold"}>Detail Lowongan Kerja Lokal</Text>
|
||||||
|
{lowonganState.findUnique.data ? (
|
||||||
|
<Paper key={lowonganState.findUnique.data.id} bg={colors['BG-trans']} p={'md'}>
|
||||||
|
<Stack gap={"xs"}>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Bekerja Sebagai</Text>
|
||||||
|
<Text fz={"lg"}>{lowonganState.findUnique.data?.posisi}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Nama Usaha</Text>
|
||||||
|
<Text fz={"lg"}>{lowonganState.findUnique.data?.namaPerusahaan}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Lokasi</Text>
|
||||||
|
<Text fz={"lg"}>{lowonganState.findUnique.data?.lokasi}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Tipe Pekerjaan</Text>
|
||||||
|
<Text fz={"lg"}>{lowonganState.findUnique.data?.tipePekerjaan}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Gaji</Text>
|
||||||
|
<Text fz={"lg"}>{lowonganState.findUnique.data?.gaji}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Deskripsi</Text>
|
||||||
|
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: lowonganState.findUnique.data?.deskripsi }} />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Kualifikasi</Text>
|
||||||
|
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: lowonganState.findUnique.data?.kualifikasi }} />
|
||||||
|
</Box>
|
||||||
|
<Flex gap={"xs"} mt={10}>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
if (lowonganState.findUnique.data) {
|
||||||
|
setSelectedId(lowonganState.findUnique.data.id);
|
||||||
|
setModalHapus(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={lowonganState.delete.loading || !lowonganState.findUnique.data}
|
||||||
|
color={"red"}
|
||||||
|
>
|
||||||
|
<IconX size={20} />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
if (lowonganState.findUnique.data) {
|
||||||
|
router.push(`/admin/ekonomi/lowongan-kerja-lokal/${lowonganState.findUnique.data.id}/edit`);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={!lowonganState.findUnique.data}
|
||||||
|
color={"green"}
|
||||||
|
>
|
||||||
|
<IconEdit size={20} />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
) : null}
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
{/* Modal Konfirmasi Hapus */}
|
||||||
|
<ModalKonfirmasiHapus
|
||||||
|
opened={modalHapus}
|
||||||
|
onClose={() => setModalHapus(false)}
|
||||||
|
onConfirm={handleHapus}
|
||||||
|
text='Apakah anda yakin ingin menghapus lowongan kerja ini?'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DetailLowonganKerjaLokal;
|
||||||
@@ -3,11 +3,33 @@ import colors from '@/con/colors';
|
|||||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||||
import { IconArrowBack } from '@tabler/icons-react';
|
import { IconArrowBack } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { KeamananEditor } from '../../../keamanan/_com/keamananEditor';
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import CreateEditor from '../../../_com/createEditor';
|
||||||
|
import lowonganKerjaState from '../../../_state/ekonomi/lowongan-kerja';
|
||||||
|
|
||||||
|
|
||||||
function CreateLowonganKerja() {
|
function CreateLowonganKerja() {
|
||||||
|
const lowonganState = useProxy(lowonganKerjaState)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
lowonganState.create.form = {
|
||||||
|
posisi: "",
|
||||||
|
namaPerusahaan: "",
|
||||||
|
lokasi: "",
|
||||||
|
tipePekerjaan: "",
|
||||||
|
gaji: "",
|
||||||
|
deskripsi: "",
|
||||||
|
kualifikasi: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await lowonganState.create.create()
|
||||||
|
resetForm()
|
||||||
|
router.push("/admin/ekonomi/lowongan-kerja-lokal")
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Box mb={10}>
|
<Box mb={10}>
|
||||||
@@ -20,33 +42,65 @@ function CreateLowonganKerja() {
|
|||||||
<Stack gap={"xs"}>
|
<Stack gap={"xs"}>
|
||||||
<Title order={4}>Create Lowongan Kerja Lokal</Title>
|
<Title order={4}>Create Lowongan Kerja Lokal</Title>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Pekerjaan</Text>}
|
value={lowonganState.create.form.posisi}
|
||||||
placeholder='Masukkan pekerjaan'
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.posisi = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Posisi</Text>}
|
||||||
|
placeholder='Masukkan posisi'
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nama Usaha</Text>}
|
value={lowonganState.create.form.namaPerusahaan}
|
||||||
placeholder='Masukkan nama usaha'
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.namaPerusahaan = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Nama Perusahaan</Text>}
|
||||||
|
placeholder='Masukkan nama perusahaan'
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Alamat Usaha</Text>}
|
value={lowonganState.create.form.lokasi}
|
||||||
placeholder='Masukkan alamat usaha'
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.lokasi = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Lokasi</Text>}
|
||||||
|
placeholder='Masukkan lokasi'
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nomor Telepon</Text>}
|
value={lowonganState.create.form.tipePekerjaan}
|
||||||
placeholder='Masukkan nomor telepon'
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.tipePekerjaan = val.target.value;
|
||||||
|
}}
|
||||||
|
label={<Text fw={"bold"} fz={"sm"}>Tipe Pekerjaan</Text>}
|
||||||
|
placeholder='Masukkan tipe pekerjaan'
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
value={lowonganState.create.form.gaji}
|
||||||
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.gaji = val.target.value;
|
||||||
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
||||||
placeholder='Masukkan gaji'
|
placeholder='Masukkan gaji'
|
||||||
/>
|
/>
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={"bold"} fz={"sm"}>Deskripsi Lowongan Kerja</Text>
|
<Text fw={"bold"} fz={"sm"}>Deskripsi Lowongan Kerja</Text>
|
||||||
<KeamananEditor
|
<CreateEditor
|
||||||
showSubmit={false}
|
value={lowonganState.create.form.deskripsi}
|
||||||
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.deskripsi = val;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"sm"}>Kualifikasi Lowongan Kerja</Text>
|
||||||
|
<CreateEditor
|
||||||
|
value={lowonganState.create.form.kualifikasi}
|
||||||
|
onChange={(val) => {
|
||||||
|
lowonganState.create.form.kualifikasi = val;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Group>
|
<Group>
|
||||||
<Button bg={colors['blue-button']}>Submit</Button>
|
<Button bg={colors['blue-button']} onClick={handleSubmit}>Submit</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
'use client'
|
|
||||||
import colors from '@/con/colors';
|
|
||||||
import { Box, Button, Flex, Paper, Stack, Text } from '@mantine/core';
|
|
||||||
import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
|
|
||||||
import { useRouter } from 'next/navigation';
|
|
||||||
// import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
|
||||||
|
|
||||||
function DetailLowonganKerjaLokal() {
|
|
||||||
const router = useRouter();
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Box mb={10}>
|
|
||||||
<Button variant="subtle" onClick={() => router.back()}>
|
|
||||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
<Paper w={{ base: "100%", md: "50%" }} bg={colors['white-1']} p={'md'}>
|
|
||||||
<Stack>
|
|
||||||
<Text fz={"xl"} fw={"bold"}>Detail Lowongan Kerja Lokal</Text>
|
|
||||||
|
|
||||||
<Paper bg={colors['BG-trans']} p={'md'}>
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Bekerja Sebagai</Text>
|
|
||||||
<Text>Karyawan</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Nama Usaha</Text>
|
|
||||||
<Text>BIBD</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Alamat Usaha</Text>
|
|
||||||
<Text>Jalan In Aja</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Nomor Telepon</Text>
|
|
||||||
<Text>0896232831883</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Waktu Kerja</Text>
|
|
||||||
<Text>Full Time</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Gaji selama 1 bulan</Text>
|
|
||||||
<Text>Rp. 3.000.000</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"}>Deskripsi Lowongan Kerja</Text>
|
|
||||||
<Text> Pekerjaan dengan gaji Rp. 3.000.000</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Flex gap={"xs"}>
|
|
||||||
<Button color="red">
|
|
||||||
<IconX size={20} />
|
|
||||||
</Button>
|
|
||||||
<Button onClick={() => router.push('/admin/ekonomi/lowongan-kerja-lokal/edit')} color="green">
|
|
||||||
<IconEdit size={20} />
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
|
|
||||||
{/* Modal Hapus
|
|
||||||
<ModalKonfirmasiHapus
|
|
||||||
opened={modalHapus}
|
|
||||||
onClose={() => setModalHapus(false)}
|
|
||||||
onConfirm={handleHapus}
|
|
||||||
text="Apakah anda yakin ingin menghapus potensi ini?"
|
|
||||||
/> */}
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DetailLowonganKerjaLokal;
|
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
'use client'
|
|
||||||
import colors from '@/con/colors';
|
|
||||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
|
||||||
import { IconArrowBack } from '@tabler/icons-react';
|
|
||||||
import { useRouter } from 'next/navigation';
|
|
||||||
import { KeamananEditor } from '../../../keamanan/_com/keamananEditor';
|
|
||||||
|
|
||||||
|
|
||||||
function EditLowonganKerja() {
|
|
||||||
const router = useRouter();
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Box mb={10}>
|
|
||||||
<Button onClick={() => router.back()} variant='subtle' color={'blue'}>
|
|
||||||
<IconArrowBack color={colors['blue-button']} size={25}/>
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Paper w={{base: '100%', md: '50%'}} bg={colors['white-1']} p={'md'}>
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Title order={4}>Edit Lowongan Kerja Lokal</Title>
|
|
||||||
<TextInput
|
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Pekerjaan</Text>}
|
|
||||||
placeholder='Masukkan pekerjaan'
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nama Usaha</Text>}
|
|
||||||
placeholder='Masukkan nama usaha'
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Alamat Usaha</Text>}
|
|
||||||
placeholder='Masukkan alamat usaha'
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nomor Telepon</Text>}
|
|
||||||
placeholder='Masukkan nomor telepon'
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
|
||||||
placeholder='Masukkan gaji'
|
|
||||||
/>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"} fz={"sm"}>Deskripsi Lowongan Kerja</Text>
|
|
||||||
<KeamananEditor
|
|
||||||
showSubmit={false}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Group>
|
|
||||||
<Button bg={colors['blue-button']}>Submit</Button>
|
|
||||||
</Group>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EditLowonganKerja;
|
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import HeaderSearch from '../../_com/header';
|
import HeaderSearch from '../../_com/header';
|
||||||
import JudulList from '../../_com/judulList';
|
import JudulList from '../../_com/judulList';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import lowonganKerjaState from '../../_state/ekonomi/lowongan-kerja';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
|
||||||
function LowonganKerjaLokal() {
|
function LowonganKerjaLokal() {
|
||||||
return (
|
return (
|
||||||
@@ -20,7 +23,20 @@ function LowonganKerjaLokal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ListLowonganKerjaLokal() {
|
function ListLowonganKerjaLokal() {
|
||||||
|
const lowonganState = useProxy(lowonganKerjaState)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
lowonganState.findMany.load();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!lowonganState.findMany.data) {
|
||||||
|
return (
|
||||||
|
<Stack py={10}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Box py={10}>
|
<Box py={10}>
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
<Paper bg={colors['white-1']} p={'md'}>
|
||||||
@@ -38,16 +54,18 @@ function ListLowonganKerjaLokal() {
|
|||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
<TableTr>
|
{lowonganState.findMany.data?.map((item) => (
|
||||||
<TableTd>Karyawan</TableTd>
|
<TableTr key={item.id}>
|
||||||
<TableTd>BIBD</TableTd>
|
<TableTd>{item.posisi}</TableTd>
|
||||||
<TableTd>Jalan In Aja</TableTd>
|
<TableTd>{item.namaPerusahaan}</TableTd>
|
||||||
<TableTd>
|
<TableTd>{item.lokasi}</TableTd>
|
||||||
<Button onClick={() => router.push('/admin/ekonomi/lowongan-kerja-lokal/detail')}>
|
<TableTd>
|
||||||
|
<Button onClick={() => router.push(`/admin/ekonomi/lowongan-kerja-lokal/${item.id}`)}>
|
||||||
<IconDeviceImac size={20} />
|
<IconDeviceImac size={20} />
|
||||||
</Button>
|
</Button>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
|
))}
|
||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Elysia from "elysia";
|
import Elysia from "elysia";
|
||||||
import PasarDesa from "./pasar-desa";
|
import PasarDesa from "./pasar-desa";
|
||||||
import KategoriMakanan from "./kategori-makanan";
|
import KategoriMakanan from "./kategori-makanan";
|
||||||
|
import LowonganKerja from "./lowongan-kerja";
|
||||||
|
|
||||||
const Ekonomi = new Elysia({
|
const Ekonomi = new Elysia({
|
||||||
prefix: "/api/ekonomi",
|
prefix: "/api/ekonomi",
|
||||||
@@ -8,5 +9,6 @@ const Ekonomi = new Elysia({
|
|||||||
})
|
})
|
||||||
.use(PasarDesa)
|
.use(PasarDesa)
|
||||||
.use(KategoriMakanan)
|
.use(KategoriMakanan)
|
||||||
|
.use(LowonganKerja)
|
||||||
|
|
||||||
export default Ekonomi
|
export default Ekonomi
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
type FormCreate = {
|
||||||
|
posisi: string;
|
||||||
|
namaPerusahaan: string;
|
||||||
|
lokasi: string;
|
||||||
|
tipePekerjaan: string;
|
||||||
|
gaji: string;
|
||||||
|
deskripsi: string;
|
||||||
|
kualifikasi: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function lowonganKerjaCreate(context: Context) {
|
||||||
|
const body = context.body as FormCreate;
|
||||||
|
|
||||||
|
const lowonganKerja = await prisma.lowonganPekerjaan.create({
|
||||||
|
data: {
|
||||||
|
posisi: body.posisi,
|
||||||
|
namaPerusahaan: body.namaPerusahaan,
|
||||||
|
lokasi: body.lokasi,
|
||||||
|
tipePekerjaan: body.tipePekerjaan,
|
||||||
|
gaji: body.gaji,
|
||||||
|
deskripsi: body.deskripsi,
|
||||||
|
kualifikasi: body.kualifikasi,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Success create lowongan kerja",
|
||||||
|
data: lowonganKerja,
|
||||||
|
};
|
||||||
|
}
|
||||||
34
src/app/api/[[...slugs]]/_lib/ekonomi/lowongan-kerja/del.ts
Normal file
34
src/app/api/[[...slugs]]/_lib/ekonomi/lowongan-kerja/del.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
const lowonganKerjaDelete = async (context: Context) => {
|
||||||
|
const id = context.params?.id as string;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
body: "ID tidak diberikan",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const lowonganKerja = await prisma.lowonganPekerjaan.findUnique({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!lowonganKerja) {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
body: "Lowongan kerja tidak ditemukan",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.lowonganPekerjaan.delete({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "Lowongan kerja berhasil dihapus",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default lowonganKerjaDelete;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export default async function lowonganKerjaFindMany() {
|
||||||
|
try {
|
||||||
|
const data = await prisma.lowonganPekerjaan.findMany({
|
||||||
|
where: { isActive: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Success fetch lowongan kerja",
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Find many error:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Failed fetch lowongan kerja",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export default async function lowonganKerjaFindUnique(request: Request){
|
||||||
|
const url = new URL(request.url);
|
||||||
|
const pathSegments = url.pathname.split('/');
|
||||||
|
const id = pathSegments[pathSegments.length - 1];
|
||||||
|
|
||||||
|
if(!id){
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "ID tidak boleh kosong",
|
||||||
|
}, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof id !== 'string') {
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "ID tidak valid",
|
||||||
|
}, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await prisma.lowonganPekerjaan.findUnique({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "Lowongan kerja tidak ditemukan",
|
||||||
|
}, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success fetch lowongan kerja by ID",
|
||||||
|
data,
|
||||||
|
}, {
|
||||||
|
status: 200,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Find by ID error:", e);
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil lowongan kerja: " + (e instanceof Error ? e.message : 'Unknown error'),
|
||||||
|
}, {
|
||||||
|
status: 500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import Elysia, { t } from "elysia";
|
||||||
|
import lowonganKerjaCreate from "./create";
|
||||||
|
import lowonganKerjaFindMany from "./findMany";
|
||||||
|
import lowonganKerjaFindUnique from "./findUnique";
|
||||||
|
import lowonganKerjaDelete from "./del";
|
||||||
|
import lowonganKerjaUpdate from "./updt";
|
||||||
|
|
||||||
|
const LowonganKerja = new Elysia({prefix: "/lowongankerja", tags: ["Ekonomi/Lowongan Kerja"]})
|
||||||
|
.post("/create", lowonganKerjaCreate, {
|
||||||
|
body: t.Object({
|
||||||
|
posisi: t.String(),
|
||||||
|
namaPerusahaan: t.String(),
|
||||||
|
lokasi: t.String(),
|
||||||
|
tipePekerjaan: t.String(),
|
||||||
|
gaji: t.String(),
|
||||||
|
deskripsi: t.String(),
|
||||||
|
kualifikasi: t.String(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.get("/find-many", lowonganKerjaFindMany)
|
||||||
|
.get("/:id", async (context) => {
|
||||||
|
const response = await lowonganKerjaFindUnique(new Request(context.request));
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.delete("/del/:id", lowonganKerjaDelete)
|
||||||
|
.put("/:id", async (context) => {
|
||||||
|
const response = await lowonganKerjaUpdate(context);
|
||||||
|
return response;
|
||||||
|
}, {
|
||||||
|
body: t.Object({
|
||||||
|
posisi: t.String(),
|
||||||
|
namaPerusahaan: t.String(),
|
||||||
|
lokasi: t.String(),
|
||||||
|
tipePekerjaan: t.String(),
|
||||||
|
gaji: t.String(),
|
||||||
|
deskripsi: t.String(),
|
||||||
|
kualifikasi: t.String(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export default LowonganKerja;
|
||||||
64
src/app/api/[[...slugs]]/_lib/ekonomi/lowongan-kerja/updt.ts
Normal file
64
src/app/api/[[...slugs]]/_lib/ekonomi/lowongan-kerja/updt.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
type FormUpdate = {
|
||||||
|
posisi: string;
|
||||||
|
namaPerusahaan: string;
|
||||||
|
lokasi: string;
|
||||||
|
tipePekerjaan: string;
|
||||||
|
gaji: string;
|
||||||
|
deskripsi: string;
|
||||||
|
kualifikasi: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function lowonganKerjaUpdate(context: Context){
|
||||||
|
try {
|
||||||
|
const id = context.params?.id;
|
||||||
|
const body = context.body as FormUpdate;
|
||||||
|
|
||||||
|
const { posisi, namaPerusahaan, lokasi, tipePekerjaan, gaji, deskripsi, kualifikasi } = body;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "ID tidak boleh kosong",
|
||||||
|
}, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = await prisma.lowonganPekerjaan.findUnique({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "Lowongan kerja tidak ditemukan",
|
||||||
|
}, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const updated = await prisma.lowonganPekerjaan.update({
|
||||||
|
where: { id },
|
||||||
|
data: {
|
||||||
|
posisi,
|
||||||
|
namaPerusahaan,
|
||||||
|
lokasi,
|
||||||
|
tipePekerjaan,
|
||||||
|
gaji,
|
||||||
|
deskripsi,
|
||||||
|
kualifikasi,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return Response.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success update lowongan kerja",
|
||||||
|
data: updated,
|
||||||
|
}, { status: 200 });
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Update error:", e);
|
||||||
|
return Response.json({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengupdate lowongan kerja: " + (e instanceof Error ? e.message : 'Unknown error'),
|
||||||
|
}, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user