import {
json,
redirect,
type ActionFunctionArgs,
type LoaderFunctionArgs
} from "@remix-run/node";
import {
Form,
useActionData,
useLoaderData,
useNavigation,
Link
} from "@remix-run/react";
import { useState } from "react";
import { Card, CardContent, CardHeader } from "~/components/ui/card";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import { Textarea } from "~/components/ui/textarea";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "~/components/ui/select";
import { Alert, AlertDescription } from "~/components/ui/alert";
import {
Building,
ArrowLeft,
ArrowRight,
AlertCircle,
Loader2,
CheckCircle,
MapPin,
User,
FileText,
Phone
} from "lucide-react";
// Progress Indicator Component
const ProgressIndicator = ({ currentStep = 3, totalSteps = 5 }) => {
return (
{Array.from({ length: totalSteps }, (_, index) => {
const stepNumber = index + 1;
const isActive = stepNumber === currentStep;
const isCompleted = stepNumber < currentStep;
return (
{isCompleted ? : stepNumber}
{stepNumber < totalSteps && (
)}
);
})}
);
};
// Interfaces
interface LoaderData {
phone: string;
}
interface CompanyProfileActionData {
errors?: {
companyName?: string;
ownerName?: string;
companyType?: string;
address?: string;
city?: string;
postalCode?: string;
businessType?: string;
employeeCount?: string;
serviceArea?: string;
general?: string;
};
success?: boolean;
}
export const loader = async ({
request
}: LoaderFunctionArgs): Promise => {
const url = new URL(request.url);
const phone = url.searchParams.get("phone");
if (!phone) {
return redirect("/authpengelola/requestotpforregister");
}
return json({ phone });
};
export const action = async ({
request
}: ActionFunctionArgs): Promise => {
const formData = await request.formData();
const phone = formData.get("phone") as string;
// Extract form data
const companyData = {
companyName: formData.get("companyName") as string,
ownerName: formData.get("ownerName") as string,
companyType: formData.get("companyType") as string,
address: formData.get("address") as string,
city: formData.get("city") as string,
postalCode: formData.get("postalCode") as string,
businessType: formData.get("businessType") as string,
employeeCount: formData.get("employeeCount") as string,
serviceArea: formData.get("serviceArea") as string,
description: formData.get("description") as string
};
// Validation
const errors: { [key: string]: string } = {};
if (!companyData.companyName?.trim()) {
errors.companyName = "Nama perusahaan wajib diisi";
}
if (!companyData.ownerName?.trim()) {
errors.ownerName = "Nama pemilik/direktur wajib diisi";
}
if (!companyData.companyType) {
errors.companyType = "Jenis badan usaha wajib dipilih";
}
if (!companyData.address?.trim()) {
errors.address = "Alamat lengkap wajib diisi";
}
if (!companyData.city?.trim()) {
errors.city = "Kota wajib diisi";
}
if (!companyData.postalCode?.trim()) {
errors.postalCode = "Kode pos wajib diisi";
} else if (!/^\d{5}$/.test(companyData.postalCode)) {
errors.postalCode = "Kode pos harus 5 digit angka";
}
if (!companyData.businessType) {
errors.businessType = "Jenis usaha wajib dipilih";
}
if (!companyData.employeeCount) {
errors.employeeCount = "Jumlah karyawan wajib dipilih";
}
if (!companyData.serviceArea?.trim()) {
errors.serviceArea = "Area layanan wajib diisi";
}
if (Object.keys(errors).length > 0) {
return json({ errors }, { status: 400 });
}
// Simulasi menyimpan data - dalam implementasi nyata, simpan ke database
try {
console.log("Saving company profile:", { phone, ...companyData });
// Simulasi delay API call
await new Promise((resolve) => setTimeout(resolve, 1000));
// Redirect ke step berikutnya
return redirect(
`/authpengelola/waitingapprovalfromadministrator?phone=${encodeURIComponent(
phone
)}`
);
} catch (error) {
return json(
{
errors: { general: "Gagal menyimpan data. Silakan coba lagi." }
},
{ status: 500 }
);
}
};
export default function CompletingCompanyProfile() {
const { phone } = useLoaderData();
const actionData = useActionData();
const navigation = useNavigation();
const isSubmitting = navigation.state === "submitting";
return (
{/* Progress Indicator */}
{/* Main Card */}
Profil Perusahaan
Lengkapi informasi perusahaan untuk verifikasi admin
{/* Error Alert */}
{actionData?.errors?.general && (
{actionData.errors.general}
)}
{/* Form */}
{/* Back Link */}
Kembali ke verifikasi OTP
);
}