Skip to content

Commit

Permalink
Enhance Form Service Modularity, SSO Login, and Service Search Fixes (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
newarifrh authored Sep 6, 2024
2 parents c686cf1 + 706d5dd commit c526a07
Show file tree
Hide file tree
Showing 22 changed files with 545 additions and 475 deletions.
3 changes: 2 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
VITE_API_BASE_URL=https://api-serambi.bpsbontang.com
VITE_API_BASE_URL=https://api-serambi.bpsbontang.com
VITE_HAS_LOGIN_SSO=false
3 changes: 2 additions & 1 deletion .env.staging
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
VITE_API_BASE_URL=https://staging-api-serambi.bpsbontang.com
VITE_API_BASE_URL=https://staging-api-serambi.bpsbontang.com
VITE_HAS_LOGIN_SSO=false
4 changes: 4 additions & 0 deletions Dockerfile.production
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ FROM nginx:stable-alpine-slim AS production-stage
RUN mkdir /app

COPY --from=build-stage /app/dist /app

# Remove source maps and other unwanted files
RUN find /app -name "*.map" -delete

COPY default.conf /etc/nginx/conf.d/default.conf
4 changes: 4 additions & 0 deletions Dockerfile.staging
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ FROM nginx:stable-alpine-slim AS staging-stage
RUN mkdir /app

COPY --from=build-stage /app/dist /app

# Remove source maps and other unwanted files
RUN find /app -name "*.map" -delete

COPY default.conf /etc/nginx/conf.d/default.conf
Binary file modified bun.lockb
Binary file not shown.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@ant-design/icons": "^5.4.0",
"@sentry/react": "^8.26.0",
"antd": "^5.20.2",
"js-cookie": "^3.0.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.1"
Expand All @@ -22,6 +23,7 @@
"@eslint/js": "^9.9.1",
"@sentry/vite-plugin": "^2.22.2",
"@types/bun": "^1.1.6",
"@types/js-cookie": "^3.0.6",
"@types/node": "^22.5.0",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
Expand All @@ -35,6 +37,7 @@
"tailwindcss": "^3.4.10",
"typescript": "^5.5.4",
"typescript-eslint": "^8.2.0",
"vite": "^5.4.2"
"vite": "^5.4.2",
"vite-plugin-svgr": "^4.2.0"
}
}
118 changes: 118 additions & 0 deletions public/bps.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/api/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,16 @@ export const login = async (email: string, password: string) => {

return await handleResponse(response);
};

export const logout = async () => {
const response = await fetch(`${API_BASE_URL}/v1/auth/logout`, {
method: "POST",
credentials: "include",
headers: {
"X-App-Type": "web",
"Content-Type": "application/json",
},
});

await handleResponse(response);
};
297 changes: 297 additions & 0 deletions src/components/service/FormService.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
import { getService, getServiceTags } from "@/api/Service";
import { getTeams } from "@/api/Team";
import { API_BASE_URL } from "@/configs/Constant";
import { useMediaQuery } from "@/hooks/useMediaQuery";
import { Team } from "@/types/Team";
import {
App,
Card,
Form,
Input,
Image,
Select,
SelectProps,
Upload,
Checkbox,
Button,
Empty,
Spin,
} from "antd";
import { useEffect, useState } from "react";

interface FormServiceProps {
serviceId?: string;
onSubmit: (values: any) => Promise<any>;
}
const FormService = ({ serviceId, onSubmit }: FormServiceProps) => {
const [labels, setLables] = useState<SelectProps["options"]>([]);
const [teams, setTeams] = useState<SelectProps["options"]>([]);
const [error, setError] = useState<unknown>();
const [isLoading, setIsLoading] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const { message, notification } = App.useApp();
const [image, setImage] = useState<string>();
const isMobile = useMediaQuery();
const [form] = Form.useForm();

useEffect(() => {
const fetchServiceTags = async () => {
try {
const data = await getServiceTags("all");
setLables(
data.tags.map((item: string) => ({ label: item, value: item }))
);
} catch (error) {
setError(error);
}
};

fetchServiceTags();
}, []);

useEffect(() => {
const fetchTeams = async () => {
try {
const data = await getTeams();
setTeams(
data.map((item: Team) => ({ label: item.name, value: item.id }))
);
} catch (error) {
setError(error);
}
};

fetchTeams();
}, []);

useEffect(() => {
const fetchService = async () => {
if (serviceId) {
try {
setIsLoading(true);
const data = await getService(serviceId);
form.setFieldsValue({
name: data.name,
description: data.description,
link: data.link,
teams: data.teams.map((item: { team: Team }) => item.team.id),
tags: data.tags,
image: data.imageUrl,
hasLogo: data.hasLogo,
username: data.credential?.username,
password: data.credential?.password,
note: data.credential?.note,
hasSso: data.credential?.hasSso,
});
setImage(data.imageUrl);
} catch (error) {
console.error("An error occurred: ", error);
setError(error);
notification.error({
message: "Gagal mendapatkan informasi layanan",
description:
"Terjadi kesalahan saat mendapatkan informasi layanan. Silakan coba lagi.",
});
} finally {
setIsLoading(false);
}
}
};

fetchService();
}, [form, notification, serviceId]);

const onFinish = async (values: any) => {
setIsSubmitting(true);
const result = await onSubmit(values);
if (result && !serviceId) {
form.resetFields();
setImage(undefined);
}
setIsSubmitting(false);
};

if (isLoading) {
return (
<Spin className="flex-1 flex justify-center items-center" size="large" />
);
}

if (error) {
return (
<Empty
className="flex-1 flex flex-col justify-center items-center"
description="Terjadi kesalahan"
/>
);
}

return (
<Form onFinish={onFinish} layout="vertical" form={form}>
<Card>
<Card.Grid
style={{
width: isMobile ? "100%" : "50%",
}}
hoverable={false}
>
<Form.Item
name="name"
label="Nama Layanan"
required
tooltip="Nama layanan wajib diisi"
rules={[
{ required: true, message: "Silahkan masukan nama layanan" },
]}
>
<Input placeholder="Masukkan nama layanan" />
</Form.Item>
<Form.Item
label="Deskripsi Layanan"
name="description"
required
tooltip="Deskripsi layanan wajib diisi"
rules={[
{
required: true,
message: "Silahkan masukan deskripsi layanan",
},
]}
>
<Input.TextArea rows={4} placeholder="Masukkan deskripsi layanan" />
</Form.Item>
<Form.Item
label="Tautan Layanan"
required
name={"link"}
rules={[
{
required: true,
message: "Silahkan masukan tautan layanan",
},
]}
tooltip="Tautan layanan wajib diisi"
>
<Input placeholder="Masukkan tautan layanan" />
</Form.Item>
<Form.Item
label="Tim"
name={"teams"}
required
tooltip="Tim wajib diisi"
rules={[
{
required: true,
message: "Silahkan masukan tim",
},
]}
>
<Select
mode="multiple"
allowClear
optionFilterProp="label"
placeholder="Masukan tim"
options={teams}
/>
</Form.Item>
<Form.Item label="Label Layanan" name={"tags"}>
<Select
mode="tags"
allowClear
placeholder="Masukan label layanan"
options={labels}
/>
</Form.Item>
<Form.Item
label="Foto Layanan"
name={"image"}
valuePropName="image"
required
tooltip="Foto layanan wajib diisi"
rules={[
{ required: true, message: "Silahkan masukan foto layanan" },
]}
>
<Upload
name="image"
accept="image/*,"
action={`${API_BASE_URL}/v1/services/upload`}
withCredentials={true}
maxCount={1}
onChange={(info) => {
if (info.file.status !== "uploading") {
//console.log(info.file, info.fileList);
}
if (info.file.status === "done") {
const imageUrl = info.file.response.data.imageUrl;
setImage(imageUrl);

message.success(
`${info.file.name} file uploaded successfully`
);
} else if (info.file.status === "error") {
message.error(`${info.file.name} file upload failed.`);
}
}}
>
<Image
preview={false}
className="max-w-lg max-h-96"
alt="Foto layanan"
src={image || ""}
loading="lazy"
fallback={"/default.png"}
/>
</Upload>
</Form.Item>
<p className="text-xs italic">
Foto layanan dapat berupa logo atau tangkapan layar layanan.
</p>
<p className="text-xs italic">
Khusus tangkapan layar gunakan ukuran 300 x 100.
</p>
<Form.Item name="hasLogo" valuePropName="checked">
<Checkbox>Apakah berupa logo?</Checkbox>
</Form.Item>
</Card.Grid>
<Card.Grid
style={{
width: isMobile ? "100%" : "50%",
}}
hoverable={false}
>
<Form.Item
name="username"
label="Nama Pengguna Layanan"
tooltip="Hanya diisi jika layanan memiliki kredensial selain Single Sign On"
>
<Input placeholder="Masukkan nama pengguna layanan" />
</Form.Item>
<Form.Item
name="password"
label="Kata Sandi Pengguna Layanan"
tooltip="Hanya diisi jika layanan memiliki kredensial selain Single Sign On"
>
<Input.Password
placeholder="Masukkan kata sandi pengguna layanan"
autoComplete="on"
/>
</Form.Item>
<Form.Item label="Catatan Kredensial Layanan" name="note">
<Input.TextArea rows={4} placeholder="Masukkan nama deskripsi" />
</Form.Item>
<Form.Item name="hasSso" valuePropName="checked">
<Checkbox>Apakah tersedia Single Sign On?</Checkbox>
</Form.Item>
<Form.Item>
<Button loading={isSubmitting} type="primary" htmlType="submit">
Perbarui
</Button>
</Form.Item>
</Card.Grid>
</Card>
</Form>
);
};

export default FormService;
2 changes: 1 addition & 1 deletion src/components/service/ServiceItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const ServiceItem = ({ service, onItemDeleted }: ServiceItemProps) => {
<div className="relative bg-white border rounded-md drop-shadow-sm gap-2 flex flex-col ">
{!service.hasLogo ? (
<Image
className="object-cover object-top"
className="object-cover"
height={100}
preview={false}
src={service.imageUrl}
Expand Down
2 changes: 1 addition & 1 deletion src/components/service/ServicesContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface ServicesContentProps {

const ServicesContent = ({ services, onItemDeleted }: ServicesContentProps) => {
return (
<div className="my-5 flex-1 grid gap-5 2xl:grid-cols-5 xl:grid-cols-4 lg:grid-cols-3 md:grid-cols-2 grid-cols-1 auto-rows-min">
<div className="my-5 flex-1 grid gap-5 2xl:grid-cols-5 xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 auto-rows-min">
{services.map((item: Service, index: number) => (
<ServiceItem onItemDeleted={onItemDeleted} key={index} service={item} />
))}
Expand Down
1 change: 1 addition & 0 deletions src/components/team/FormUpdateTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const FormUpdateTeam = ({ onSubmit, form }: FormUpdateTeamProps) => {
<Select
mode="multiple"
allowClear
optionFilterProp="label"
placeholder="Masukan daftar anggota tim"
options={users.map((item) => {
return {
Expand Down
Loading

0 comments on commit c526a07

Please sign in to comment.