updated mdenu

This commit is contained in:
Berkay 2025-05-03 15:13:44 +03:00
parent 71c808a5c3
commit 734dc59e38
8 changed files with 311 additions and 762 deletions

View File

@ -1,130 +1,58 @@
"use client";
import React, { useState, useEffect } from "react";
import { User, Briefcase, ChevronDown } from "lucide-react";
import {
retrieveAccessObjects,
retrieveUserSelection,
} from "@/apicalls/cookies/token";
import { Briefcase } from "lucide-react";
import { retrieveAccessObjects } from "@/apicalls/cookies/token";
import { loginSelectEmployee } from "@/apicalls/login/login";
import { EmployeeProfileLanguage } from "./language";
import { EmployeeProfileSectionProps, CompanyInfo } from "./type";
// Language definitions for employee profile section
const profileLanguage = {
tr: {
userType: "Kullanıcı Tipi",
employee: "Çalışan",
loading: "Yükleniyor...",
changeSelection: "Seçimi Değiştir",
selectCompany: "Şirket Seçin",
noCompanies: "Kullanılabilir şirket bulunamadı",
duty: "Görev",
},
en: {
userType: "User Type",
employee: "Employee",
loading: "Loading...",
changeSelection: "Change Selection",
selectCompany: "Select Company",
noCompanies: "No companies available",
duty: "Duty",
},
};
interface CompanyInfo {
uu_id: string;
public_name: string;
company_type: string;
company_address: string | null;
duty: string;
}
interface UserSelection {
userType: string;
selected: CompanyInfo;
}
interface EmployeeProfileSectionProps {
userSelectionData: UserSelection;
lang?: "en" | "tr";
}
const EmployeeProfileSection: React.FC<EmployeeProfileSectionProps> = ({
userSelectionData,
lang = "en",
}) => {
const t =
profileLanguage[lang as keyof typeof profileLanguage] || profileLanguage.en;
const EmployeeProfileSection: React.FC<EmployeeProfileSectionProps> = ({ userSelectionData, lang = "en" }) => {
const t = EmployeeProfileLanguage[lang as keyof typeof EmployeeProfileLanguage] || EmployeeProfileLanguage.en;
const [showSelectionList, setShowSelectionList] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(true);
// Initialize state with data from props
const [userSelection, setUserSelection] = useState<CompanyInfo | null>(
userSelectionData?.selected || null
);
const [selectionList, setSelectionList] = useState<CompanyInfo[] | null>(
null
);
const [availableCompanies, setAvailableCompanies] = useState<CompanyInfo[]>(
[]
);
const [userSelection, setUserSelection] = useState<CompanyInfo | null>(userSelectionData?.selected || null);
const [selectionList, setSelectionList] = useState<CompanyInfo[] | null>(null);
const [availableCompanies, setAvailableCompanies] = useState<CompanyInfo[]>([]);
const [hasMultipleOptions, setHasMultipleOptions] = useState<boolean>(false);
// Fetch access objects for selection list when needed
useEffect(() => {
if (showSelectionList && !selectionList) {
setLoading(true);
retrieveAccessObjects()
.then((accessObjectsData) => {
console.log("Access Objects:", accessObjectsData);
retrieveAccessObjects().then((accessObjectsData) => {
if (accessObjectsData && "selectionList" in accessObjectsData) {
const companies = (accessObjectsData as any).selectionList as CompanyInfo[];
setSelectionList(companies);
if (accessObjectsData && "selectionList" in accessObjectsData) {
const companies = (accessObjectsData as any)
.selectionList as CompanyInfo[];
setSelectionList(companies);
// Filter out the currently selected company
if (userSelection) {
const filteredCompanies = companies.filter(
(company) => company.uu_id !== userSelection.uu_id
);
setAvailableCompanies(filteredCompanies);
setHasMultipleOptions(filteredCompanies.length > 0);
} else {
setAvailableCompanies(companies);
setHasMultipleOptions(companies.length > 1);
}
if (userSelection) {
const filteredCompanies = companies.filter(
(company) => company.uu_id !== userSelection.uu_id
);
setAvailableCompanies(filteredCompanies);
setHasMultipleOptions(filteredCompanies.length > 0);
} else {
setAvailableCompanies(companies);
setHasMultipleOptions(companies.length > 1);
}
})
.catch((err) => {
console.error("Error fetching access objects:", err);
})
.finally(() => setLoading(false));
}
}).catch((err) => { console.error("Error fetching access objects:", err) }).finally(() => setLoading(false));
}
}, [showSelectionList, selectionList, userSelection]);
// Update user selection when props change
useEffect(() => {
if (userSelectionData?.selected) {
setUserSelection(userSelectionData.selected as CompanyInfo);
// Check if we need to fetch selection list to determine if multiple options exist
if (!selectionList) {
retrieveAccessObjects()
.then((accessObjectsData) => {
if (accessObjectsData && "selectionList" in accessObjectsData) {
const companies = (accessObjectsData as any)
.selectionList as CompanyInfo[];
setSelectionList(companies);
// Filter out the currently selected company
const filteredCompanies = companies.filter(
(company) => company.uu_id !== userSelectionData.selected.uu_id
);
setHasMultipleOptions(filteredCompanies.length > 0);
}
})
.catch((err) => {
console.error("Error fetching access objects:", err);
});
retrieveAccessObjects().then((accessObjectsData) => {
if (accessObjectsData && "selectionList" in accessObjectsData) {
const companies = (accessObjectsData as any).selectionList as CompanyInfo[];
setSelectionList(companies);
const filteredCompanies = companies.filter(
(company) => company.uu_id !== userSelectionData.selected.uu_id
);
setHasMultipleOptions(filteredCompanies.length > 0);
}
}).catch((err) => { console.error("Error fetching access objects:", err) });
}
}
}, [userSelectionData, selectionList]);
@ -132,92 +60,55 @@ const EmployeeProfileSection: React.FC<EmployeeProfileSectionProps> = ({
const handleSelectCompany = (company: any) => {
loginSelectEmployee({ company_uu_id: company.uu_id })
.then((responseData: any) => {
if (responseData?.status === 200 || responseData?.status === 202) {
// Refresh the page to update the selection
window.location.reload();
}
})
.catch((error) => {
console.error("Error selecting company:", error);
});
if (responseData?.status === 200 || responseData?.status === 202) { window.location.reload(); }
}).catch((error) => { console.error("Error selecting company:", error) });
};
if (!userSelection) {
return <div className="text-center text-gray-500">{t.loading}</div>;
} else {
return (
<div className="flex flex-col space-y-3">
<div
className={`flex items-center justify-between p-2 ${hasMultipleOptions ? "hover:bg-gray-100 cursor-pointer" : ""} rounded-lg transition-colors`}
onClick={() => hasMultipleOptions && setShowSelectionList(!showSelectionList)}
>
<div className="flex items-center space-x-3">
<div className="bg-green-100 p-2 rounded-full">
<Briefcase className="h-5 w-5 text-green-600" />
</div>
<div>
<h3 className="font-medium text-gray-900">
{userSelection.public_name} {userSelection.company_type}
</h3>
<p className="text-sm text-gray-500">{userSelection.duty}</p>
</div>
</div>
</div>
{/* Selection dropdown */}
{showSelectionList && hasMultipleOptions && (
<div className="mt-2 border rounded-lg overflow-hidden shadow-md">
<div className="bg-gray-50 p-2 border-b">
<h4 className="font-medium text-gray-700">{t.selectCompany}</h4>
</div>
<div className="max-h-60 overflow-y-auto">
{loading ? <div className="p-4 text-center text-gray-500">{t.loading}</div> : availableCompanies.length > 0 ? availableCompanies.map((company, index) => (
<div key={index} className="p-3 hover:bg-gray-50 cursor-pointer border-b last:border-b-0" onClick={() => handleSelectCompany(company)}>
<div className="font-medium">{company.public_name}</div>
{company.company_type && <div className="text-sm text-blue-600">{company.company_type}</div>}
{company.duty && <div className="text-xs text-gray-500 mt-1">{t.duty}: {company.duty}</div>}
</div>
)) : (
<div className="p-4 text-center text-gray-500">{t.noCompanies}</div>
)}
</div>
</div>
)}
</div>
);
}
return (
<div className="flex flex-col space-y-3">
{/* <div className="flex items-center space-x-3">
<div className="bg-blue-100 p-2 rounded-full">
<User className="h-6 w-6 text-blue-600" />
</div>
<div>
<h3 className="font-medium text-gray-900">{t.userType}</h3>
<p className="text-sm text-gray-600">{t.employee}</p>
</div>
</div> */}
<div
className={`flex items-center justify-between p-2 ${
hasMultipleOptions ? "hover:bg-gray-100 cursor-pointer" : ""
} rounded-lg transition-colors`}
onClick={() =>
hasMultipleOptions && setShowSelectionList(!showSelectionList)
}
>
<div className="flex items-center space-x-3">
<div className="bg-green-100 p-2 rounded-full">
<Briefcase className="h-5 w-5 text-green-600" />
</div>
<div>
<h3 className="font-medium text-gray-900">
{userSelection.public_name} {userSelection.company_type}
</h3>
<p className="text-sm text-gray-500">{userSelection.duty}</p>
</div>
</div>
</div>
{/* Selection dropdown */}
{showSelectionList && hasMultipleOptions && (
<div className="mt-2 border rounded-lg overflow-hidden shadow-md">
<div className="bg-gray-50 p-2 border-b">
<h4 className="font-medium text-gray-700">{t.selectCompany}</h4>
</div>
<div className="max-h-60 overflow-y-auto">
{loading ? (
<div className="p-4 text-center text-gray-500">{t.loading}</div>
) : availableCompanies.length > 0 ? (
availableCompanies.map((company, index) => (
<div
key={index}
className="p-3 hover:bg-gray-50 cursor-pointer border-b last:border-b-0"
onClick={() => handleSelectCompany(company)}
>
<div className="font-medium">{company.public_name}</div>
{company.company_type && (
<div className="text-sm text-blue-600">
{company.company_type}
</div>
)}
{company.duty && (
<div className="text-xs text-gray-500 mt-1">
{t.duty}: {company.duty}
</div>
)}
</div>
))
) : (
<div className="p-4 text-center text-gray-500">
{t.noCompanies}
</div>
)}
</div>
</div>
)}
</div>
);
};
export default EmployeeProfileSection;

View File

@ -3,24 +3,13 @@ import Link from "next/link";
import React, { JSX } from "react";
import { getNavigationMenu } from "./type";
function NavigationMenu({
lang,
activePage,
}: {
lang: "en" | "tr";
activePage: string;
}) {
const NavigationMenu: React.FC<{ lang: "en" | "tr"; activePage: string; }> = ({ lang, activePage }) => {
const navItems = getNavigationMenu(lang);
function createLinkComponent(url: string, title: string): JSX.Element {
return (
<Link
key={url}
href={url}
className={`px-4 py-2 rounded-md transition-colors duration-200 ${url === activePage ? "bg-emerald-500 text-white" : "bg-white hover:bg-gray-100"}`}
>
{title}
<Link key={url} href={url}
className={`px-4 py-2 rounded-md transition-colors duration-200 ${url === activePage ?
"bg-emerald-500 text-white" : "bg-white hover:bg-gray-100"}`}>{title}
</Link>
);
}

View File

@ -1,192 +1,71 @@
"use client";
import React, { useState, useEffect } from "react";
import { User, Building, Home, ChevronDown } from "lucide-react";
import { Building, Home, ChevronDown } from "lucide-react";
import { retrieveAccessObjects } from "@/apicalls/cookies/token";
import { loginSelectOccupant } from "@/apicalls/login/login";
import { useRouter } from "next/navigation";
// Language definitions for occupant profile section
const profileLanguage = {
tr: {
userType: "Kullanıcı Tipi",
occupant: "Sakin",
building: "Bina",
apartment: "Daire",
loading: "Yükleniyor...",
changeSelection: "Seçimi Değiştir",
selectOccupant: "Daire Seçin",
noOccupants: "Kullanılabilir daire bulunamadı",
},
en: {
userType: "User Type",
occupant: "Occupant",
building: "Building",
apartment: "Apartment",
loading: "Loading...",
changeSelection: "Change Selection",
selectOccupant: "Select Apartment",
noOccupants: "No apartments available",
},
};
// {
// "userType": "occupant",
// "selectionList": {
// "3fe72194-dad6-4ddc-8679-70acdbe7f619": {
// "build_uu_id": "3fe72194-dad6-4ddc-8679-70acdbe7f619",
// "build_name": "Build Example",
// "build_no": "B001",
// "occupants": [
// {
// "build_living_space_uu_id": "b67e5a37-ac04-45ab-8bca-5a3427358015",
// "part_uu_id": "441ef61b-1cc5-465b-90b2-4835d0e16540",
// "part_name": "APARTMAN DAIRESI : 1",
// "part_level": 1,
// "occupant_uu_id": "6bde6bf9-0d13-4b6f-a612-28878cd7324f",
// "description": "Daire Kiracısı",
// "code": "FL-TEN"
// }
// ]
// }
// }
// }
// Define interfaces for occupant data structures based on the access object structure
interface OccupantDetails {
build_living_space_uu_id: string;
part_uu_id: string;
part_name: string;
part_level: number;
occupant_uu_id: string;
description: string;
code: string;
[key: string]: any; // Allow other properties
}
interface BuildingInfo {
build_uu_id: string;
build_name: string;
build_no: string;
occupants: OccupantDetails[];
[key: string]: any; // Allow other properties
}
interface OccupantSelectionList {
userType: string;
selectionList: {
[key: string]: BuildingInfo;
};
}
// Interface for the selected occupant data
interface OccupantInfo {
buildName?: string;
buildNo?: string;
occupantName?: string;
description?: string;
code?: string;
part_name?: string;
build_living_space_uu_id?: string;
[key: string]: any; // Allow other properties
}
interface UserSelection {
userType: string;
selected: OccupantInfo;
}
interface OccupantProfileSectionProps {
userSelectionData: UserSelection;
lang?: "en" | "tr";
}
import { OccupantProfileLanguage } from "./language";
import { OccupantSelectionList, BuildingInfo, OccupantInfo, OccupantDetails, OccupantProfileSectionProps } from "./type";
const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
userSelectionData,
lang = "en",
}) => {
const t =
profileLanguage[lang as keyof typeof profileLanguage] || profileLanguage.en;
const router = useRouter();
const [showSelectionList, setShowSelectionList] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(true);
// Initialize state with data from props
const [userSelection, setUserSelection] = useState<OccupantInfo | null>(
userSelectionData?.selected || null
);
const [selectionList, setSelectionList] =
useState<OccupantSelectionList | null>(null);
const [availableOccupants, setAvailableOccupants] = useState<any[]>([]);
const [userSelection, setUserSelection] = useState<OccupantInfo | null>(userSelectionData?.selected || null);
const [selectionList, setSelectionList] = useState<OccupantSelectionList | null>(null);
const [hasMultipleOptions, setHasMultipleOptions] = useState<boolean>(false);
const [selectedBuildingKey, setSelectedBuildingKey] = useState<string | null>(
null
);
const [buildings, setBuildings] = useState<{ [key: string]: BuildingInfo }>(
{}
);
const [selectedBuildingKey, setSelectedBuildingKey] = useState<string | null>(null);
const [buildings, setBuildings] = useState<{ [key: string]: BuildingInfo }>({});
const [loading, setLoading] = useState<boolean>(true);
const [availableOccupants, setAvailableOccupants] = useState<OccupantInfo[]>([]);
const t = handleProfileChange(OccupantProfileLanguage, lang);
function handleProfileChange(languages: any, lang: string) {
return languages[lang as keyof typeof languages] || languages.en;
}
// Fetch access objects for selection list when needed
useEffect(() => {
if (showSelectionList && !selectionList) {
setLoading(true);
retrieveAccessObjects()
.then((accessObjectsData) => {
console.log("Access Objects:", accessObjectsData);
retrieveAccessObjects().then((accessObjectsData) => {
if (accessObjectsData && accessObjectsData.selectionList) {
const data = accessObjectsData as OccupantSelectionList;
setSelectionList(data);
setBuildings(data.selectionList);
if (accessObjectsData && accessObjectsData.selectionList) {
const data = accessObjectsData as OccupantSelectionList;
setSelectionList(data);
setBuildings(data.selectionList);
const buildingKeys = Object.keys(data.selectionList);
let totalOccupants = 0;
let currentBuildingKey = null;
let currentOccupantId = null;
// Check if there are multiple buildings or multiple occupants across all buildings
const buildingKeys = Object.keys(data.selectionList);
let totalOccupants = 0;
let currentBuildingKey = null;
let currentOccupantId = null;
buildingKeys.forEach((key) => {
const building = data.selectionList[key];
if (building.occupants && building.occupants.length > 0) {
totalOccupants += building.occupants.length;
// Count total occupants and find current building/occupant
buildingKeys.forEach((key) => {
const building = data.selectionList[key];
if (building.occupants && building.occupants.length > 0) {
totalOccupants += building.occupants.length;
// Try to find the current user's building and occupant
if (userSelection) {
building.occupants.forEach((occupant) => {
if (
occupant.build_living_space_uu_id ===
userSelection.build_living_space_uu_id
) {
currentBuildingKey = key;
currentOccupantId = occupant.build_living_space_uu_id;
}
});
}
if (userSelection) {
building.occupants.forEach((occupant) => {
if (occupant.build_living_space_uu_id === userSelection.build_living_space_uu_id) {
currentBuildingKey = key;
currentOccupantId = occupant.build_living_space_uu_id;
}
});
}
});
// Set whether there are multiple options
setHasMultipleOptions(totalOccupants > 1);
// If we found the current building, set it as selected
if (currentBuildingKey) {
setSelectedBuildingKey(currentBuildingKey);
}
}
})
.catch((err) => {
console.error("Error fetching access objects:", err);
})
});
setHasMultipleOptions(totalOccupants > 1);
if (currentBuildingKey) { setSelectedBuildingKey(currentBuildingKey) }
}
})
.catch((err) => { console.error("Error fetching access objects:", err) })
.finally(() => setLoading(false));
}
}, [showSelectionList, userSelection]);
// Update user selection when props change
useEffect(() => {
if (userSelectionData?.selected) {
setUserSelection(userSelectionData.selected as OccupantInfo);
// Check if we need to fetch selection list to determine if multiple options exist
if (!selectionList) {
retrieveAccessObjects()
.then((accessObjectsData) => {
@ -195,7 +74,6 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
setSelectionList(data);
setBuildings(data.selectionList);
// Count total occupants across all buildings
let totalOccupants = 0;
let currentBuildingKey = null;
@ -203,13 +81,8 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
const building = data.selectionList[key];
if (building.occupants && building.occupants.length > 0) {
totalOccupants += building.occupants.length;
// Try to find the current user's building
building.occupants.forEach((occupant) => {
if (
userSelectionData.selected.build_living_space_uu_id ===
occupant.build_living_space_uu_id
) {
if (userSelectionData.selected.build_living_space_uu_id === occupant.build_living_space_uu_id) {
currentBuildingKey = key;
}
});
@ -217,25 +90,18 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
});
setHasMultipleOptions(totalOccupants > 1);
if (currentBuildingKey) {
setSelectedBuildingKey(currentBuildingKey);
}
if (currentBuildingKey) { setSelectedBuildingKey(currentBuildingKey) }
}
})
.catch((err) => {
console.error("Error fetching access objects:", err);
});
.catch((err) => { console.error("Error fetching access objects:", err) });
}
}
}, [userSelectionData, selectionList]);
// Helper function to process occupant data
const processOccupantData = (data: OccupantSelectionList) => {
if (!data.selectionList) return;
const occupantList: any[] = [];
// Process the building/occupant structure
Object.keys(data.selectionList).forEach((buildKey) => {
const building = data.selectionList[buildKey];
if (building.occupants && building.occupants.length > 0) {
@ -253,7 +119,6 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
setAvailableOccupants(occupantList);
};
// Process occupant data when selection menu is opened or when selectionList changes
useEffect(() => {
if (showSelectionList && selectionList && selectionList.selectionList) {
setLoading(true);
@ -263,18 +128,9 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
}, [showSelectionList, selectionList]);
const handleSelectOccupant = (occupant: any) => {
loginSelectOccupant({
build_living_space_uu_id: occupant.build_living_space_uu_id,
})
.then((responseData: any) => {
if (responseData?.status === 200 || responseData?.status === 202) {
// Refresh the page to update the selection
window.location.reload();
}
})
.catch((error) => {
console.error("Error selecting occupant:", error);
});
loginSelectOccupant({ build_living_space_uu_id: occupant.build_living_space_uu_id })
.then((responseData: any) => { if (responseData?.status === 200 || responseData?.status === 202) { window.location.reload() } })
.catch((error) => { console.error("Error selecting occupant:", error) });
};
if (!userSelection) {
@ -283,16 +139,6 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
return (
<div className="flex flex-col space-y-3">
{/* <div className="flex items-center space-x-3">
<div className="bg-blue-100 p-2 rounded-full">
<User className="h-6 w-6 text-blue-600" />
</div>
<div>
<h3 className="font-medium text-gray-900">{t.userType}</h3>
<p className="text-sm text-gray-600">{t.occupant}</p>
</div>
</div> */}
{userSelection?.buildName && (
<div className="flex items-center space-x-3">
<div className="bg-amber-100 p-2 rounded-full">
@ -307,12 +153,8 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
{userSelection?.part_name && (
<div
className={`flex items-center justify-between space-x-3 p-2 ${
hasMultipleOptions ? "hover:bg-gray-100 cursor-pointer" : ""
} rounded-lg transition-colors`}
onClick={() =>
hasMultipleOptions && setShowSelectionList(!showSelectionList)
}
className={`flex items-center justify-between space-x-3 p-2 ${hasMultipleOptions ? "hover:bg-gray-100 cursor-pointer" : ""} rounded-lg transition-colors`}
onClick={() => hasMultipleOptions && setShowSelectionList(!showSelectionList)}
>
<div className="flex items-center space-x-3">
<div className="bg-purple-100 p-2 rounded-full">
@ -321,18 +163,10 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
<div>
<h3 className="font-medium text-gray-900">{t.apartment}</h3>
<p className="text-sm text-gray-600">{userSelection.part_name}</p>
{userSelection.description && (
<p className="text-xs text-gray-500">
{userSelection.description}
</p>
)}
{userSelection.description && <p className="text-xs text-gray-500">{userSelection.description}</p>}
</div>
</div>
{hasMultipleOptions && (
<div className="text-xs text-blue-600 flex items-center">
{t.changeSelection} <ChevronDown className="h-3 w-3 ml-1" />
</div>
)}
{hasMultipleOptions && <div className="text-xs text-blue-600 flex items-center">{t.changeSelection} <ChevronDown className="h-3 w-3 ml-1" /></div>}
</div>
)}
@ -347,7 +181,6 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
<div className="p-4 text-center text-gray-500">{t.loading}</div>
) : buildings && Object.keys(buildings).length > 0 ? (
selectedBuildingKey ? (
// Second layer: Occupants in the selected building
<div>
<div className="bg-gray-100 p-2 border-b flex justify-between items-center">
<h5 className="font-medium text-gray-700">
@ -357,67 +190,42 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
className="text-xs text-blue-600"
onClick={() => setSelectedBuildingKey(null)}
>
Back to buildings
{t.backToBuildings}
</button>
</div>
{buildings[selectedBuildingKey].occupants.length > 0 ? (
buildings[selectedBuildingKey].occupants.map(
(occupant, index) => {
// Skip the currently selected occupant
if (
userSelection &&
occupant.build_living_space_uu_id ===
userSelection.build_living_space_uu_id
) {
return null;
}
if (userSelection && occupant.build_living_space_uu_id === userSelection.build_living_space_uu_id) { return null }
return (
<div
key={index}
className="p-3 hover:bg-gray-50 cursor-pointer border-b last:border-b-0"
onClick={() => handleSelectOccupant(occupant)}
>
<div className="font-medium">
{occupant.description || "Apartment"}
</div>
<div className="text-sm text-gray-600">
{occupant.part_name}
</div>
{occupant.code && (
<div className="text-xs text-gray-500 mt-1">
{t.apartment} {occupant.code}
</div>
)}
<div className="font-medium">{occupant.description || "Apartment"}</div>
<div className="text-sm text-gray-600">{occupant.part_name}</div>
{occupant.code && <div className="text-xs text-gray-500 mt-1">{t.apartment} {occupant.code}</div>}
</div>
);
}
)
) : (
<div className="p-4 text-center text-gray-500">
{t.noOccupants}
</div>
<div className="p-4 text-center text-gray-500">{t.noOccupants}</div>
)}
</div>
) : (
// First layer: Buildings list
Object.keys(buildings).map((buildingKey, index) => {
const building = buildings[buildingKey];
// Skip buildings with no occupants or only the current occupant
if (!building.occupants || building.occupants.length === 0) {
return null;
}
// Check if this building has any occupants other than the current one
if (userSelection) {
const hasOtherOccupants = building.occupants.some(
(occupant) =>
occupant.build_living_space_uu_id !==
userSelection.build_living_space_uu_id
(occupant) => occupant.build_living_space_uu_id !== userSelection.build_living_space_uu_id
);
if (!hasOtherOccupants) {
return null;
}
if (!hasOtherOccupants) { return null }
}
return (
@ -427,23 +235,17 @@ const OccupantProfileSection: React.FC<OccupantProfileSectionProps> = ({
onClick={() => setSelectedBuildingKey(buildingKey)}
>
<div className="font-medium">{building.build_name}</div>
<div className="text-sm text-gray-600">
No: {building.build_no}
</div>
<div className="text-sm text-gray-600">{t.buildNo}: {building.build_no}</div>
<div className="text-xs text-gray-500 mt-1">
{building.occupants.length}{" "}
{building.occupants.length === 1
? t.apartment.toLowerCase()
: t.apartment.toLowerCase() + "s"}
{building.occupants.length === 1 ? t.apartment.toLowerCase() : t.apartment.toLowerCase() + "s"}
</div>
</div>
);
})
)
) : (
<div className="p-4 text-center text-gray-500">
{t.noOccupants}
</div>
<div className="p-4 text-center text-gray-500">{t.noOccupants}</div>
)}
</div>
</div>

View File

@ -1,9 +1,6 @@
"use client";
import React from "react";
interface ProfileLoadingStateProps {
loadingText: string;
}
import { ProfileLoadingStateProps } from "./type";
const ProfileLoadingState: React.FC<ProfileLoadingStateProps> = ({ loadingText }) => {
return (

View File

@ -0,0 +1,92 @@
export const dashboardLanguage = {
tr: {
dashboard: "Kontrol Paneli",
loading: "Yükleniyor...",
},
en: {
dashboard: "Control Panel",
loading: "Loading...",
},
};
export const NavigationLanguage = {
en: {
"/dashboard": "Dashboard",
"/append/event": "Event Board",
"/append/service": "Service Board",
"/application": "Application Board",
},
tr: {
"/dashboard": "Kontrol Paneli",
"/append/event": "Event Paneli",
"/append/service": "Servis Paneli",
"/application": "Uygulama Paneli",
},
};
export const EmployeeProfileLanguage = {
tr: {
userType: "Kullanıcı Tipi",
employee: "Çalışan",
loading: "Yükleniyor...",
changeSelection: "Seçimi Değiştir",
selectCompany: "Şirket Seçin",
noCompanies: "Kullanılabilir şirket bulunamadı",
duty: "Görev",
},
en: {
userType: "User Type",
employee: "Employee",
loading: "Loading...",
changeSelection: "Change Selection",
selectCompany: "Select Company",
noCompanies: "No companies available",
duty: "Duty",
},
};
export const OccupantProfileLanguage = {
tr: {
userType: "Kullanıcı Tipi",
occupant: "Sakin",
building: "Bina",
apartment: "Daire",
loading: "Yükleniyor...",
changeSelection: "Seçimi Değiştir",
selectOccupant: "Daire Seçin",
noOccupants: "Kullanılabilir daire bulunamadı",
backToBuildings: "Binalara Geri Dön",
buildNo: "Bina No",
},
en: {
userType: "User Type",
occupant: "Occupant",
building: "Building",
apartment: "Apartment",
loading: "Loading...",
changeSelection: "Change Selection",
selectOccupant: "Select Apartment",
noOccupants: "No apartments available",
backToBuildings: "Back to buildings",
buildNo: "Build No",
},
};
// {
// "userType": "occupant",
// "selectionList": {
// "3fe72194-dad6-4ddc-8679-70acdbe7f619": {
// "build_uu_id": "3fe72194-dad6-4ddc-8679-70acdbe7f619",
// "build_name": "Build Example",
// "build_no": "B001",
// "occupants": [
// {
// "build_living_space_uu_id": "b67e5a37-ac04-45ab-8bca-5a3427358015",
// "part_uu_id": "441ef61b-1cc5-465b-90b2-4835d0e16540",
// "part_name": "APARTMAN DAIRESI : 1",
// "part_level": 1,
// "occupant_uu_id": "6bde6bf9-0d13-4b6f-a612-28878cd7324f",
// "description": "Daire Kiracısı",
// "code": "FL-TEN"
// }
// ]
// }
// }
// }

View File

@ -1,31 +1,15 @@
"use client";
import React, { useEffect, useState, Suspense, JSX } from "react";
import { retrieveUserSelection } from "@/apicalls/cookies/token";
import { ClientMenuProps, UserSelection } from "@/validations/menu/menu";
import { dashboardLanguage } from "./language";
import EmployeeProfileSection from "./EmployeeProfileSection";
import OccupantProfileSection from "./OccupantProfileSection";
import ProfileLoadingState from "./ProfileLoadingState";
import {
ClientMenuProps,
UserSelection,
} from "@/validations/menu/menu";
import NavigationMenu from "./NavigationMenu";
// Language definitions for dashboard title
const dashboardLanguage = {
tr: {
dashboard: "Kontrol Paneli",
loading: "Yükleniyor...",
},
en: {
dashboard: "Control Panel",
loading: "Loading...",
},
};
const ClientMenu: React.FC<ClientMenuProps> = ({ lang, activePage }) => {
const t = dashboardLanguage[lang as keyof typeof dashboardLanguage] || dashboardLanguage.en;
const [loading, setLoading] = useState<boolean>(true);
const [userType, setUserType] = useState<string | null>(null);
const [userSelectionData, setUserSelectionData] = useState<UserSelection | null>(null);
@ -65,15 +49,10 @@ const ClientMenu: React.FC<ClientMenuProps> = ({ lang, activePage }) => {
return (
<div className="w-full bg-white shadow-sm rounded-lg overflow-hidden">
<div className="p-4 border-b border-gray-200">
<h2 className="text-xl font-bold text-center text-gray-800">
{t.dashboard}
</h2>
<h2 className="text-xl font-bold text-center text-gray-800">{t.dashboard}</h2>
</div>
<div className="p-4 border-b border-gray-200 bg-gray-50">
<Suspense
fallback={<div className="text-center py-4">{t.loading}</div>}
>
<Suspense fallback={<div className="text-center py-4">{t.loading}</div>}>
{createProfileComponent()}
</Suspense>
</div>

View File

@ -1,255 +0,0 @@
const Individual = {
name: "Individual",
lg: {
tr: "Birey",
en: "Individual",
},
siteUrl: "/individual",
};
const User = {
name: "User",
lg: {
tr: "Kullanıcı",
en: "User",
},
siteUrl: "/user",
};
const Build = {
name: "Build",
lg: {
tr: "Apartman",
en: "Build",
},
siteUrl: "/build",
};
const Dashboard = {
name: "Dashboard",
lg: {
tr: "Pano",
en: "Dashboard",
},
siteUrl: "/dashboard",
};
const BuildParts = {
name: "BuildParts",
lg: {
tr: "Daireler",
en: "Build Parts",
},
siteUrl: "/build/parts",
};
const BuildArea = {
name: "BuildArea",
lg: {
tr: "Daire Alanları",
en: "Build Area",
},
siteUrl: "/build/area",
};
const ManagementAccounting = {
name: "ManagementAccounting",
lg: {
tr: "Yönetim Cari Hareketler",
en: "ManagementAccounting",
},
siteUrl: "/management/accounting",
};
const ManagementBudget = {
name: "ManagementBudget",
lg: {
tr: "Yönetim Bütçe İşlemleri",
en: "Management Budget",
},
siteUrl: "/management/budget",
};
const BuildPartsAccounting = {
name: "BuildPartsAccounting",
lg: {
tr: "Daire Cari Hareketler",
en: "Build Parts Accounting",
},
siteUrl: "/build/parts/accounting",
};
const AnnualMeeting = {
name: "AnnualMeeting",
lg: {
tr: "Yıllık Olağan Toplantı Tanımlama ve Davet",
en: "Annual Meetings and Invitations",
},
siteUrl: "/annual/meeting",
};
const AnnualMeetingClose = {
name: "AnnualMeetingClose",
lg: {
tr: "Yıllık Olağan Toplantı kapatma ve Cari Yaratma",
en: "Annual Meeting Close and Accountings",
},
siteUrl: "/annual/meeting/close",
};
const EmergencyMeeting = {
name: "EmergencyMeeting",
lg: {
tr: "Acil Toplantı Tanımlama ve Davet",
en: "Emergency Meeting and Invitations",
},
siteUrl: "/emergency/meeting",
};
const EmergencyMeetingClose = {
name: "EmergencyMeetingClose",
lg: {
tr: "Acil Olağan Toplantı kapatma ve Cari Yaratma",
en: "Emergency Meeting Close and Accountings",
},
siteUrl: "/emergency/meeting/close",
};
const MeetingParticipations = {
name: "MeetingParticipations",
lg: {
tr: "Toplantı Katılım İşlemleri",
en: "Meeting Participations",
},
siteUrl: "/meeting/participation",
};
const TenantSendMessageToBuildManager = {
name: "TenantSendMessageToBuildManager",
lg: {
tr: "Bina Yöneticisine Mesaj Gönder",
en: "Send Message to Build Manager",
},
siteUrl: "/tenant/messageToBM",
};
const TenantSendMessageToOwner = {
name: "TenantSendMessageToOwner",
lg: {
tr: "Sahibine Mesaj Gönder",
en: "Send Message to Owner",
},
siteUrl: "/tenant/messageToOwner",
};
const TenantAccountView = {
name: "TenantAccountView",
lg: {
tr: "Kiracı Cari Hareketleri",
en: "Tenant Accountings",
},
siteUrl: "/tenant/accounting",
};
const Menu = [
{
name: "Dashboard",
lg: {
tr: "Pano",
en: "Dashboard",
},
subList: [
{
name: "Dashboard",
lg: {
tr: "Pano",
en: "Dashboard",
},
subList: [Dashboard],
},
],
},
{
name: "Definitions",
lg: {
tr: "Tanımlar",
en: "Definitions",
},
subList: [
{
name: "People",
lg: {
tr: "Kişiler",
en: "People",
},
subList: [Individual, User],
},
{
name: "Building",
lg: {
tr: "Binalar",
en: "Building",
},
subList: [Build, BuildParts, BuildArea],
},
],
},
{
name: "Building Management",
lg: {
tr: "Bina Yönetimi",
en: "Building Management",
},
subList: [
{
name: "Management Accounting",
lg: {
tr: "Cari işlemler",
en: "Management Accounting",
},
subList: [ManagementAccounting, ManagementBudget, BuildPartsAccounting],
},
{
name: "Meetings",
lg: {
tr: "Toplantılar",
en: "Meetings",
},
subList: [
AnnualMeeting,
AnnualMeetingClose,
EmergencyMeeting,
EmergencyMeetingClose,
MeetingParticipations,
],
},
],
},
{
name: "Tenants",
lg: {
tr: "Kiracı İşlemleri",
en: "Tenant Actions",
},
subList: [
{
name: "Accountings",
lg: {
tr: "Kiracı Cari Hareketler",
en: "Tenant Accountings",
},
subList: [TenantAccountView],
},
{
name: "Messages",
lg: {
tr: "Mesaj Gönder",
en: "Send Messages",
},
subList: [TenantSendMessageToBuildManager, TenantSendMessageToOwner],
},
],
},
];
export default Menu;

View File

@ -1,21 +1,75 @@
export const NavigationLanguage = {
en: {
"/dashboard": "Dashboard",
"/append/event": "Event Board",
"/append/service": "Service Board",
"/application": "Application Board",
},
tr: {
"/dashboard": "Kontrol Paneli",
"/append/event": "Event Paneli",
"/append/service": "Servis Paneli",
"/application": "Uygulama Paneli",
},
};
import { NavigationLanguage } from "./language";
export interface ProfileLoadingStateProps {
loadingText: string;
}
export interface CompanyInfo {
uu_id: string;
public_name: string;
company_type: string;
company_address: string | null;
duty: string;
}
export interface UserSelection {
userType: string;
selected: CompanyInfo;
}
export interface EmployeeProfileSectionProps {
userSelectionData: UserSelection;
lang?: "en" | "tr";
}
export interface OccupantDetails {
build_living_space_uu_id: string;
part_uu_id: string;
part_name: string;
part_level: number;
occupant_uu_id: string;
description: string;
code: string;
[key: string]: any;
}
export interface BuildingInfo {
build_uu_id: string;
build_name: string;
build_no: string;
occupants: OccupantDetails[];
[key: string]: any;
}
export interface OccupantSelectionList {
userType: string;
selectionList: {
[key: string]: BuildingInfo;
};
}
export interface OccupantInfo {
buildName?: string;
buildNo?: string;
occupantName?: string;
description?: string;
code?: string;
part_name?: string;
build_living_space_uu_id?: string;
[key: string]: any;
}
export interface OccupantUserSelection {
userType: string;
selected: OccupantInfo;
}
export interface OccupantProfileSectionProps {
userSelectionData: OccupantUserSelection;
lang?: "en" | "tr";
}
export function getNavigationMenu(lang: string) {
return (
NavigationLanguage[lang as keyof typeof NavigationLanguage] ||
NavigationLanguage.en
);
const language = lang as keyof typeof NavigationLanguage;
return NavigationLanguage[language] || NavigationLanguage.en;
}