prod-wag-backend-automate-s.../web_services/management_frontend/src/webPages/auth/select/LoginOccupant.tsx

110 lines
4.2 KiB
TypeScript

"use client";
import React, { useState, useTransition, useEffect } from "react";
import { useRouter } from "next/navigation";
import { LoginOccupantProps } from "./types";
import { selectOccupantHook } from "./hook";
function LoginOccupant({
selectionList,
translation,
lang
}: LoginOccupantProps) {
const Router = useRouter();
const [isPending, startTransition] = useTransition();
const [error, setError] = useState<string | null>(null);
const [jsonText, setJsonText] = useState<string | null>(null);
const onSubmitOccupant = async (data: any) => {
selectOccupantHook(startTransition, data, setError, setJsonText, Router, lang)
};
const isArrayLengthZero = Array.isArray(selectionList) && selectionList.length === 0;
// Render an occupant card with consistent styling
const OccupantCard = ({ occupant, buildKey, idx }: { occupant: any, buildKey: string, idx: number }) => (
<div
key={`${buildKey}-${idx}`}
className="w-full p-4 mb-3 bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow-md transition-all cursor-pointer hover:translate-x-1"
onClick={() => onSubmitOccupant({ build_living_space_uu_id: occupant.build_living_space_uu_id })}
>
<div className="flex flex-col">
{/* Occupant description and code */}
<div className="flex items-center justify-between mb-2">
<h3 className="text-lg font-semibold text-gray-800">{occupant.description}</h3>
<span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
{occupant.code}
</span>
</div>
{/* Part name */}
<div className="mb-1 text-sm text-gray-700 font-medium">
{occupant.part_name}
</div>
{/* Level information */}
<div className="text-xs text-gray-500">
<span className="font-medium">{translation.level}:</span> {occupant.part_level}
</div>
</div>
</div>
);
// Render a building section with its occupants
const BuildingSection = ({ building, buildKey }: { building: any, buildKey: string }) => (
<div key={buildKey} className="mb-6">
<div className="p-3 bg-gray-50 border border-gray-200 rounded-lg mb-3">
<h2 className="text-lg font-semibold text-gray-800 flex items-center">
<svg className="w-5 h-5 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg>
<span>{building.build_name}</span>
<span className="ml-2 px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded-full">No: {building.build_no}</span>
</h2>
</div>
<div className="space-y-2">
{building.occupants.map((occupant: any, idx: number) => (
<OccupantCard key={idx} occupant={occupant} buildKey={buildKey} idx={idx} />
))}
</div>
</div>
);
return (
<div className="w-full max-w-md mx-auto">
<h1 className="text-2xl font-bold text-gray-900 mb-2">{translation.occupantSelection}</h1>
<p className="text-sm text-gray-500 mb-6">{translation.loggedInAs}</p>
{/* No occupants available */}
{!isArrayLengthZero ? (
<div className="text-center p-6 bg-gray-50 rounded-lg border border-gray-200">
<p className="text-gray-600">{translation.noSelections}</p>
</div>
) : (
/* Building sections with occupants */
<div>
{Object.keys(selectionList).map((buildKey: string) => (
<BuildingSection
key={buildKey}
building={selectionList[buildKey]}
buildKey={buildKey}
/>
))}
</div>
)}
{/* Show error if any */}
{error && <p className="mt-4 text-sm text-red-600">{error}</p>}
{/* Loading indicator */}
{isPending && (
<div className="mt-4 flex justify-center">
<div className="animate-spin h-5 w-5 border-2 border-blue-600 rounded-full border-t-transparent"></div>
</div>
)}
</div>
);
}
export default LoginOccupant;