user selection compoleted tested

This commit is contained in:
Berkay 2025-06-15 19:05:48 +03:00
parent a48e560ece
commit 9fb517fa15
24 changed files with 574 additions and 313 deletions

View File

@ -6,11 +6,13 @@ from .supers_events import (
SuperAccountRecordsUpdateEvent, SuperAccountRecordsUpdateEvent,
SuperAccountRecordsDeleteEvent, SuperAccountRecordsDeleteEvent,
) )
from .flat_representative import FlatRepresentativeAccountRecordsListEvent
AccountRecordsRouterCluster = RouterCluster(name="AccountRecordsRouterCluster") AccountRecordsRouterCluster = RouterCluster(name="AccountRecordsRouterCluster")
AccountRecordsListEventCluster = EventCluster(name="AccountRecordsListEventCluster", endpoint_uu_id=endpoints_index["AccountRecordsList"]) AccountRecordsListEventCluster = EventCluster(name="AccountRecordsListEventCluster", endpoint_uu_id=endpoints_index["AccountRecordsList"])
AccountRecordsListEventCluster.add_event(SuperAccountRecordsListEvent) AccountRecordsListEventCluster.add_event(SuperAccountRecordsListEvent)
AccountRecordsListEventCluster.add_event(FlatRepresentativeAccountRecordsListEvent)
AccountRecordsCreateEventCluster = EventCluster(name="AccountRecordsCreateEventCluster", endpoint_uu_id=endpoints_index["AccountRecordsCreate"]) AccountRecordsCreateEventCluster = EventCluster(name="AccountRecordsCreateEventCluster", endpoint_uu_id=endpoints_index["AccountRecordsCreate"])
AccountRecordsCreateEventCluster.add_event(SuperAccountRecordsCreateEvent) AccountRecordsCreateEventCluster.add_event(SuperAccountRecordsCreateEvent)

View File

@ -0,0 +1,60 @@
from typing import Any
from Initializer.event_clusters import Event
from Validations.response import (
PaginateOnly,
Pagination,
PaginationResult,
PostgresResponseSingle,
PostgresResponse,
EndpointResponse
)
from Validations.defaults.validations import CommonHeaders
from Schemas import AccountRecords
from Extensions.Middlewares.token_provider import TokenProvider
# List all account records endpoint Flat Representative
FlatRepresentativeAccountRecordsListEvent = Event(
name="flat_representative_account_records_list",
key="7cb248d3-d75a-4d28-8be5-f147089ce654",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Flat Representative Account Records List all flat representative users endpoint",
)
class FlatRepresentativeAccountRecordsListPydantic:
uu_id: str
bank_date: datetime.datetime
currency_value: float
process_name: str
def flat_representative_account_records_list_callable(list_options: PaginateOnly, header: CommonHeaders):
list_options = PaginateOnly(**list_options.model_dump())
token_object = TokenProvider.get_dict_from_redis(token=header.token)
if not token_object.is_occupant:
raise Exception("Forbidden for employees")
pagination_query = {}
if list_options.query:
pagination_query = FlatRepresentativeAccountRecordsListPydantic(**list_options.query)
with AccountRecords.new_session() as db_session:
AccountRecords.set_session(db_session)
if pagination_query:
account_records_list = AccountRecords.query.filter(
*AccountRecords.convert(pagination_query),
AccountRecords.build_parts_id == token_object.selected_occupant.build_id
)
else:
account_records_list = AccountRecords.query.filter(
AccountRecords.build_parts_id == token_object.selected_occupant.build_id
)
pagination = Pagination(data=account_records_list)
pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=account_records_list, pagination=pagination, response_model=FlatRepresentativeAccountRecordsListPydantic)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response
FlatRepresentativeAccountRecordsListEvent.event_callable = flat_representative_account_records_list_callable

View File

@ -7,8 +7,7 @@ from config import api_config
from validations.request.auth.validations import ( from validations.request.auth.validations import (
RequestLogin, RequestLogin,
RequestResetPassword, RequestResetPassword,
RequestSelectLiving, RequestSelect,
RequestSelectEmployee,
RequestCreatePassword, RequestCreatePassword,
RequestChangePassword, RequestChangePassword,
RequestForgotPasswordPhone, RequestForgotPasswordPhone,
@ -44,7 +43,7 @@ auth_route_select_living = "AuthSelectLiving"
description="Selection of users company or occupant type", description="Selection of users company or occupant type",
operation_id=endpoints_index[auth_route_select_living] operation_id=endpoints_index[auth_route_select_living]
) )
def select_living(data: Union[RequestSelectLiving, RequestSelectEmployee], headers: CommonHeaders = Depends(CommonHeaders.as_dependency)): def select_living(data: Union[RequestSelect], headers: CommonHeaders = Depends(CommonHeaders.as_dependency)):
"""Select token object company or occupant type""" """Select token object company or occupant type"""
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
return AuthHandlers.LoginHandler.authentication_select_company_or_occupant_type(request=headers.request, data=data) return AuthHandlers.LoginHandler.authentication_select_company_or_occupant_type(request=headers.request, data=data)

View File

@ -5,8 +5,9 @@ from config import api_config
from Schemas import ( from Schemas import (
Users, Users,
People, People,
BuildLivingSpace, Build,
BuildParts, BuildParts,
BuildLivingSpace,
OccupantTypes, OccupantTypes,
Employees, Employees,
Addresses, Addresses,
@ -78,6 +79,8 @@ class LoginHandler:
user_handler, other_domains_list, main_domain = UserHandlers(), [], "" user_handler, other_domains_list, main_domain = UserHandlers(), [], ""
found_user = user_handler.check_user_exists(access_key=data.access_key, db_session=db_session) found_user = user_handler.check_user_exists(access_key=data.access_key, db_session=db_session)
redis_handler = RedisHandlers()
with mongo_handler.collection(f"{str(found_user.related_company)}*Domain") as collection: with mongo_handler.collection(f"{str(found_user.related_company)}*Domain") as collection:
result = collection.find_one({"user_uu_id": str(found_user.uu_id)}) result = collection.find_one({"user_uu_id": str(found_user.uu_id)})
if not result: if not result:
@ -133,15 +136,13 @@ class LoginHandler:
person_uu_id=str(list_employees[0]["People.uu_id"]), request=dict(headers.request.headers), domain_list=other_domains_list, person_uu_id=str(list_employees[0]["People.uu_id"]), request=dict(headers.request.headers), domain_list=other_domains_list,
companies_uu_id_list=companies_uu_id_list, companies_id_list=companies_id_list, duty_uu_id_list=duty_uu_id_list, duty_id_list=duty_id_list, companies_uu_id_list=companies_uu_id_list, companies_id_list=companies_id_list, duty_uu_id_list=duty_uu_id_list, duty_id_list=duty_id_list,
).model_dump() ).model_dump()
employee_uuid = str(companies_list[0]["uu_id"])
print('employee_uuid', employee_uuid)
set_to_redis_dict = dict( set_to_redis_dict = dict(
user=found_user, token=model_value, add_uuid=employee_uuid, user=found_user, token=model_value,
header_info=dict(language=headers.language, domain=headers.domain, timezone=headers.timezone), header_info=dict(language=headers.language, domain=headers.domain, timezone=headers.timezone),
) )
user_dict = found_user.get_dict() user_dict = found_user.get_dict()
person_dict = found_user.person.get_dict() person_dict = found_user.person.get_dict()
if access_token := RedisHandlers().set_object_to_redis(**set_to_redis_dict): if access_token := redis_handler.set_object_to_redis(**set_to_redis_dict):
return { return {
"access_token": access_token, "access_token": access_token,
"user_type": UserType.employee.name, "user_type": UserType.employee.name,
@ -166,12 +167,15 @@ class LoginHandler:
language = headers.request.headers.get("language", "tr") language = headers.request.headers.get("language", "tr")
domain = headers.request.headers.get("domain", None) domain = headers.request.headers.get("domain", None)
timezone = headers.request.headers.get("tz", None) or "GMT+3" timezone = headers.request.headers.get("tz", None) or "GMT+3"
BuildLivingSpace.set_session(db_session)
BuildParts.set_session(db_session) BuildParts.set_session(db_session)
OccupantTypes.set_session(db_session) OccupantTypes.set_session(db_session)
user_handler = UserHandlers() user_handler = UserHandlers()
found_user = user_handler.check_user_exists(access_key=data.access_key, db_session=db_session) found_user = user_handler.check_user_exists(access_key=data.access_key, db_session=db_session)
other_domains_list, main_domain = [], "" other_domains_list, main_domain = [], ""
redis_handler = RedisHandlers()
with mongo_handler.collection(f"{str(found_user.related_company)}*Domain") as collection: with mongo_handler.collection(f"{str(found_user.related_company)}*Domain") as collection:
result = collection.find_one({"user_uu_id": str(found_user.uu_id)}) result = collection.find_one({"user_uu_id": str(found_user.uu_id)})
if not result: if not result:
@ -189,6 +193,10 @@ class LoginHandler:
if not living_spaces: if not living_spaces:
raise ValueError("EYS_0006") raise ValueError("EYS_0006")
user_dict = found_user.get_dict()
person_dict = found_user.person.get_dict()
for living_space in living_spaces: for living_space in living_spaces:
build_part = BuildParts.query.filter(BuildParts.id == living_space.build_parts_id).first() build_part = BuildParts.query.filter(BuildParts.id == living_space.build_parts_id).first()
if not build_part: if not build_part:
@ -197,28 +205,40 @@ class LoginHandler:
build = build_part.buildings build = build_part.buildings
occupant_type = OccupantTypes.query.filter(OccupantTypes.id == living_space.occupant_type_id).first() occupant_type = OccupantTypes.query.filter(OccupantTypes.id == living_space.occupant_type_id).first()
occupant_data = { occupant_data = {
"build_living_space_uu_id": str(living_space.uu_id), "part_uu_id": str(build_part.uu_id), "part_name": build_part.part_name(), "part_level": build_part.part_level, "build_living_space_uu_id": str(living_space.uu_id), "part_uu_id": str(build_part.uu_id), "part_name": build_part.part_name(db=db_session),
"occupant_uu_id": str(occupant_type.uu_id), "description": occupant_type.occupant_description, "code": occupant_type.occupant_code, "part_level": build_part.part_level, "occupant_uu_id": str(occupant_type.uu_id), "description": occupant_type.occupant_description,
"code": occupant_type.occupant_code,
} }
build_key = str(build.uu_id) build_key = str(build.uu_id)
if build_key not in occupants_selection_dict: if build_key not in occupants_selection_dict:
occupants_selection_dict[build_key] = {"build_uu_id": build_key, "build_name": build.build_name, "build_no": build.build_no, "occupants": [occupant_data],} occupants_selection_dict[build_key] = {"build_uu_id": build_key, "build_name": build.build_name, "build_no": build.build_no, "occupants": [occupant_data]}
else: else:
occupants_selection_dict[build_key]["occupants"].append(occupant_data) occupants_selection_dict[build_key]["occupants"].append(occupant_data)
person = found_user.person person = found_user.person
model_value = OccupantTokenObject( model_value = OccupantTokenObject(
user_type=UserType.occupant.value, user_uu_id=str(found_user.uu_id), user_id=found_user.id, person_id=person.id, user_type=UserType.occupant.value, user_uu_id=str(found_user.uu_id), user_id=found_user.id, person_id=person.id,
person_uu_id=str(person.uu_id), domain_list=other_domains_list, request=dict(request.headers), available_occupants=occupants_selection_dict, person_uu_id=str(person.uu_id), domain_list=other_domains_list, request=dict(headers.request.headers), available_occupants=occupants_selection_dict,
).model_dump() ).model_dump()
redis_handler = RedisHandlers()
if access_token := redis_handler.set_object_to_redis( set_redis_dict = dict(user=found_user, token=model_value, header_info=dict(language=language, domain=domain, timezone=timezone))
user=found_user, token=model_value, add_uuid=living_space.uu_id, if access_token := redis_handler.set_object_to_redis(**set_redis_dict):
header_info=dict(language=language, domain=domain, timezone=timezone) return {
): "access_token": access_token,
return {"access_token": access_token, "user_type": UserType.occupant.name, "selection_list": occupants_selection_dict} "user_type": UserType.occupant.name,
raise ValueError("Something went wrong") "user": {
"uuid": user_dict["uu_id"], "avatar": user_dict["avatar"], "email": user_dict["email"], "phone_number": user_dict["phone_number"], "user_tag": user_dict["user_tag"],
"password_expiry_begins": str(arrow.get(user_dict["password_expiry_begins"]).shift(days=int(user_dict["password_expires_day"]))),
"person": {
"uuid": person_dict["uu_id"], "firstname": person_dict["firstname"], "surname": person_dict["surname"],
"middle_name": person_dict["middle_name"], "sex_code": person_dict["sex_code"], "person_tag": person_dict["person_tag"],
"country_code": person_dict["country_code"], "birth_date": person_dict["birth_date"],
},
},
"selection_list": occupants_selection_dict,
}
raise ValueError("Something went wrong")
@classmethod @classmethod
def authentication_login_with_domain_and_creds(cls, headers: CommonHeaders, data: Any): def authentication_login_with_domain_and_creds(cls, headers: CommonHeaders, data: Any):
@ -264,10 +284,12 @@ class LoginHandler:
with Users.new_session() as db_session: with Users.new_session() as db_session:
if data.uuid not in token_dict.companies_uu_id_list: if data.uuid not in token_dict.companies_uu_id_list:
ValueError("EYS_0011") ValueError("EYS_0011")
list_of_returns = ( list_of_returns = (
Employees.id, Employees.uu_id, People.id, People.uu_id, Users.id, Users.uu_id, Companies.id, Companies.uu_id, Employees.id, Employees.uu_id, People.id, People.uu_id, Users.id, Users.uu_id, Companies.id, Companies.uu_id, Companies.public_name, Companies.company_type,
Departments.id, Departments.uu_id, Duty.id, Duty.uu_id, Addresses.id, Addresses.letter_address, Staff.id, Staff.uu_id, Departments.id, Departments.uu_id, Duty.id, Duty.uu_id, Addresses.id, Addresses.letter_address, Staff.id, Staff.uu_id, Duty.duty_name,
Duties.id, Duties.uu_id, Duties.id, Duties.uu_id, BuildParts.id, BuildParts.uu_id, BuildParts.part_name, BuildParts.part_level, BuildParts.part_code,
OccupantTypes.id, OccupantTypes.uu_id, OccupantTypes.occupant_type, OccupantTypes.occupant_description, Addresses.letter_address
) )
selected_company_query = db_session.query(*list_of_returns selected_company_query = db_session.query(*list_of_returns
@ -298,82 +320,76 @@ class LoginHandler:
filter_endpoints_and_events = db_session.query(EndpointRestriction.operation_uu_id, Events.function_code filter_endpoints_and_events = db_session.query(EndpointRestriction.operation_uu_id, Events.function_code
).join(EndpointRestriction, EndpointRestriction.id == Events.endpoint_id).filter().all() ).join(EndpointRestriction, EndpointRestriction.id == Events.endpoint_id).filter().all()
reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events} reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
# Get reachable applications # Get reachable applications
reachable_app_codes = Application2Employee.get_application_codes(employee_id=int(result_with_keys_dict['Employees.id']), db=db_session) reachable_app_codes = Application2Employee.get_application_codes(employee_id=int(result_with_keys_dict['Employees.id']), db=db_session)
company_token = CompanyToken( add_company = {
company_uu_id=str(result_with_keys_dict['Companies.uu_id']), "uu_id": str(result_with_keys_dict["Employees.uu_id"]),
company_id=int(result_with_keys_dict['Companies.id']), "public_name": result_with_keys_dict["Companies.public_name"],
department_id=int(result_with_keys_dict['Departments.id']), "company_type": result_with_keys_dict["Companies.company_type"],
department_uu_id=str(result_with_keys_dict['Departments.uu_id']), "company_address": result_with_keys_dict["Addresses.letter_address"],
duty_id=int(result_with_keys_dict['Duty.id']), "duty": result_with_keys_dict["Duty.duty_name"],
duty_uu_id=str(result_with_keys_dict['Duty.uu_id']), "company_uuid": str(result_with_keys_dict["Companies.uu_id"])
bulk_duties_id=int(result_with_keys_dict['Duties.id']), }
staff_id=int(result_with_keys_dict['Staff.id']),
staff_uu_id=str(result_with_keys_dict['Staff.uu_id']),
employee_id=int(result_with_keys_dict['Employees.id']),
employee_uu_id=str(result_with_keys_dict['Employees.uu_id']),
reachable_event_codes=reachable_event_codes,
reachable_app_codes=reachable_app_codes,
)
redis_handler = RedisHandlers() redis_handler = RedisHandlers()
redis_result = redis_handler.update_token_at_redis( user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
token=access_token, add_payload=company_token, add_uuid=str(result_with_keys_dict['Employees.uu_id']) redis_result = redis_handler.update_token_at_redis(token=access_token, add_payload=add_company, user_uuid=user_uu_id)
)
return {"selected_uu_id": data.uuid} return {"selected_uu_id": data.uuid}
@classmethod @classmethod
def handle_occupant_selection(cls, access_token: str, data: Any, token_dict: TokenDictType): def handle_occupant_selection(cls, access_token: str, data: Any, token_dict: TokenDictType):
"""Handle occupant type selection""" """Handle occupant type selection"""
with BuildLivingSpace.new_session() as db: with BuildLivingSpace.new_session() as db:
# Get selected occupant type BuildLivingSpace.set_session(db)
selected_build_living_space: BuildLivingSpace = BuildLivingSpace.filter_one(BuildLivingSpace.uu_id == data.build_living_space_uu_id, db=db).data BuildParts.set_session(db)
if not selected_build_living_space: Users.set_session(db)
list_of_returns = (
BuildLivingSpace.id, BuildLivingSpace.uu_id, OccupantTypes.id, OccupantTypes.uu_id, OccupantTypes.occupant_type, BuildParts.id, BuildParts.uu_id, Build.id, Build.uu_id,
BuildParts.id, BuildParts.part_level, OccupantTypes.occupant_description, OccupantTypes.occupant_code, People.id, People.uu_id
)
selected_build_living_space_query = db.query(*list_of_returns
).join(OccupantTypes, OccupantTypes.id == BuildLivingSpace.occupant_type_id
).join(BuildParts, BuildParts.id == BuildLivingSpace.build_parts_id
).join(Build, Build.id == BuildParts.build_id
).join(People, People.id == BuildLivingSpace.person_id
).filter(BuildLivingSpace.uu_id == data.uuid)
selected_build_living_space_first = selected_build_living_space_query.first()
if not selected_build_living_space_first:
raise ValueError("EYS_0012") raise ValueError("EYS_0012")
result_with_keys_dict = {}
for ix, selected_build_living_space_item in enumerate(selected_build_living_space_first):
result_with_keys_dict[str(list_of_returns[ix])] = selected_build_living_space_item
# Get reachable events filter_endpoints_and_events = db.query(EndpointRestriction.operation_uu_id, Events.function_code
reachable_event_codes = Event2Occupant.get_event_codes(build_living_space_id=selected_build_living_space.id, db=db) ).join(EndpointRestriction, EndpointRestriction.id == Events.endpoint_id).filter().all()
occupant_type = OccupantTypes.filter_one_system(OccupantTypes.id == selected_build_living_space.occupant_type_id, db=db).data reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
build_part = BuildParts.filter_one(BuildParts.id == selected_build_living_space.build_parts_id, db=db)
build = build_part.buildings
reachable_app_codes = Application2Occupant.get_application_codes(build_living_space_id=selected_build_living_space.id, db=db)
# responsible_employee = Employees.filter_one(
# Employees.id == build_part.responsible_employee_id,
# db=db,
# ).data
# related_company = RelationshipEmployee2Build.filter_one(
# RelationshipEmployee2Build.member_id == build.id,
# db=db,
# ).data
# Get company
# company_related = Companies.filter_one(
# Companies.id == related_company.company_id,
# db=db,
# ).data
# Create occupant token # Get reachable applications
occupant_token = OccupantToken( reachable_app_codes = Application2Occupant.get_application_codes(build_living_space_id=selected_build_living_space_first.id, db=db)
living_space_id=selected_build_living_space.id,
living_space_uu_id=selected_build_living_space.uu_id.__str__(), build_part = BuildParts.query.filter(BuildParts.id == result_with_keys_dict['BuildParts.id']).first()
occupant_type_id=occupant_type.id, if not build_part:
occupant_type_uu_id=occupant_type.uu_id.__str__(), raise ValueError("EYS_0013")
occupant_type=occupant_type.occupant_type,
build_id=build.id, add_build_living_space = {
build_uuid=build.uu_id.__str__(), "build_living_space_uu_id": str(data.uuid),
build_part_id=build_part.id, "part_uu_id": str(result_with_keys_dict['BuildParts.uu_id']),
build_part_uuid=build_part.uu_id.__str__(), "part_name": build_part.part_name(db=db),
# responsible_employee_id=responsible_employee.id, "part_level": result_with_keys_dict['BuildParts.part_level'],
# responsible_employee_uuid=responsible_employee.uu_id.__str__(), "occupant_uu_id": str(result_with_keys_dict['OccupantTypes.uu_id']),
# responsible_company_id=company_related.id, "description": result_with_keys_dict['OccupantTypes.occupant_description'],
# responsible_company_uuid=company_related.uu_id.__str__(), "code": result_with_keys_dict['OccupantTypes.occupant_code']
reachable_event_codes=reachable_event_codes, }
reachable_app_codes=reachable_app_codes,
)
redis_handler = RedisHandlers() redis_handler = RedisHandlers()
redis_handler.update_token_at_redis(
token=access_token, add_payload=occupant_token, add_uuid=occupant_token.living_space_uu_id user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
) redis_handler.update_token_at_redis(token=access_token, add_payload=add_build_living_space, user_uuid=user_uu_id)
return {"selected_uu_id": occupant_token.living_space_uu_id} return {"selected_uu_id": data.uuid}
@classmethod @classmethod
def authentication_select_company_or_occupant_type(cls, request: Any, data: Any): def authentication_select_company_or_occupant_type(cls, request: Any, data: Any):
@ -469,3 +485,30 @@ class AuthHandlers:
LoginHandler: LoginHandler = LoginHandler() LoginHandler: LoginHandler = LoginHandler()
PasswordHandler: PasswordHandler = PasswordHandler() PasswordHandler: PasswordHandler = PasswordHandler()
# Get selected occupant type
# selected_build_living_space: BuildLivingSpace = BuildLivingSpace.filter_one(BuildLivingSpace.uu_id == data.build_living_space_uu_id, db=db).data
# if not selected_build_living_space:
# raise ValueError("EYS_0012")
# occupant_type = OccupantTypes.filter_one_system(OccupantTypes.id == selected_build_living_space.occupant_type_id, db=db).data
# build_part = BuildParts.filter_one(BuildParts.id == selected_build_living_space.build_parts_id, db=db)
# build = build_part.buildings
# reachable_app_codes = Application2Occupant.get_application_codes(build_living_space_id=selected_build_living_space.id, db=db)
# responsible_employee = Employees.filter_one(
# Employees.id == build_part.responsible_employee_id,
# db=db,
# ).data
# related_company = RelationshipEmployee2Build.filter_one(
# RelationshipEmployee2Build.member_id == build.id,
# db=db,
# ).data
# Get company
# company_related = Companies.filter_one(
# Companies.id == related_company.company_id,
# db=db,
# ).data
# Get reachable events
# reachable_event_codes = Event2Occupant.get_event_codes(build_living_space_id=selected_build_living_space.id, db=db)

View File

@ -14,7 +14,7 @@ class RequestVerifyOTP(BaseModel):
otp: str otp: str
class RequestSelectEmployee(BaseModel): class RequestSelect(BaseModel):
uuid: str uuid: str
@ -23,10 +23,6 @@ class RequestResetPassword(BaseModel):
password: str password: str
re_password: str re_password: str
class RequestSelectLiving(BaseModel):
uuid: str
class RequestCreatePassword(BaseModel): class RequestCreatePassword(BaseModel):
password_token: str password_token: str
password: str password: str

View File

@ -0,0 +1,58 @@
from typing import Any
from Initializer.event_clusters import Event
from Validations.response import (
PaginateOnly,
Pagination,
PaginationResult,
PostgresResponseSingle,
PostgresResponse,
EndpointResponse
)
from Validations.defaults.validations import CommonHeaders
from Schemas import People
from Extensions.Middlewares.token_provider import TokenProvider
# List all people endpoint Flat Tenant
FlatTenantPeopleListEvent = Event(
name="flat_tenant_people_list",
key="7cb248d3-d75a-4d28-8be5-f147089ce654",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Flat Tenant People List all flat tenant users endpoint",
)
class FlatTenantPeopleListPydantic:
...
def flat_tenant_people_list_callable(list_options: PaginateOnly, header: CommonHeaders):
list_options = PaginateOnly(**list_options.model_dump())
token_object = TokenProvider.get_dict_from_redis(token=header.token)
if not token_object.is_occupant:
raise Exception("Forbidden for employees")
pagination_query = {}
if list_options.query:
pagination_query = FlatTenantPeopleListPydantic(**list_options.query)
with People.new_session() as db_session:
People.set_session(db_session)
if pagination_query:
people_list = People.query.filter(
*People.convert(pagination_query),
People.build_parts_id == token_object.selected_occupant.build_id
)
else:
people_list = People.query.filter(
People.build_parts_id == token_object.selected_occupant.build_id
)
pagination = Pagination(data=people_list)
pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=people_list, pagination=pagination, response_model=FlatTenantPeopleListPydantic)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response
FlatTenantPeopleListEvent.event_callable = flat_tenant_people_list_callable

View File

@ -36,6 +36,7 @@ class TokenProvider:
""" """
token_to_use, user_uu_id_to_use = token or "*", user_uu_id or "*" token_to_use, user_uu_id_to_use = token or "*", user_uu_id or "*"
list_of_token_dict, auth_key_list = [], [cls.AUTH_TOKEN, token_to_use, user_uu_id_to_use] list_of_token_dict, auth_key_list = [], [cls.AUTH_TOKEN, token_to_use, user_uu_id_to_use]
print("auth_key_list", auth_key_list)
if token: if token:
result = RedisActions.get_json(list_keys=auth_key_list, limit=1) result = RedisActions.get_json(list_keys=auth_key_list, limit=1)
if first_record := result.first: if first_record := result.first:
@ -56,7 +57,8 @@ class TokenProvider:
Retrieve token object from Redis using token and user_uu_id Retrieve token object from Redis using token and user_uu_id
""" """
token_to_use, user_uu_id_to_use = token or "*", user_uu_id or "*" token_to_use, user_uu_id_to_use = token or "*", user_uu_id or "*"
list_of_token_dict, auth_key_list = [], [cls.AUTH_TOKEN, token_to_use, user_uu_id_to_use, "*"] list_of_token_dict, auth_key_list = [], [cls.AUTH_TOKEN, token_to_use, user_uu_id_to_use]
print("auth_key_list", auth_key_list)
if token: if token:
result = RedisActions.get_json(list_keys=auth_key_list, limit=1) result = RedisActions.get_json(list_keys=auth_key_list, limit=1)
if first_record := result.first: if first_record := result.first:

View File

@ -33,7 +33,7 @@ class RedisHandlers:
@classmethod @classmethod
def get_object_from_redis(cls, access_token: str) -> TokenDictType: def get_object_from_redis(cls, access_token: str) -> TokenDictType:
redis_response = RedisActions.get_json(list_keys=[cls.AUTH_TOKEN, access_token, "*", "*"]) redis_response = RedisActions.get_json(list_keys=[cls.AUTH_TOKEN, access_token, "*"])
if not redis_response.status: if not redis_response.status:
raise ValueError("EYS_0001") raise ValueError("EYS_0001")
if redis_object := redis_response.first: if redis_object := redis_response.first:
@ -41,30 +41,27 @@ class RedisHandlers:
raise ValueError("EYS_0002") raise ValueError("EYS_0002")
@classmethod @classmethod
def set_object_to_redis(cls, user: Users, token, header_info, add_uuid: str): def set_object_to_redis(cls, user: Users, token, header_info):
result_delete = RedisActions.delete(list_keys=[cls.AUTH_TOKEN, "*", str(user.uu_id), add_uuid]) result_delete = RedisActions.delete(list_keys=[cls.AUTH_TOKEN, "*", str(user.uu_id)])
generated_access_token = PasswordModule.generate_access_token() generated_access_token = PasswordModule.generate_access_token()
keys = [cls.AUTH_TOKEN, generated_access_token, str(user.uu_id)] keys = [cls.AUTH_TOKEN, generated_access_token, str(user.uu_id)]
if add_uuid:
keys.append(add_uuid)
RedisActions.set_json(list_keys=keys, value={**token, **header_info}, expires={"hours": 1, "minutes": 30})
return generated_access_token
RedisActions.set_json(list_keys=keys, value={**token, **header_info}, expires={"hours": 1, "minutes": 30}) RedisActions.set_json(list_keys=keys, value={**token, **header_info}, expires={"hours": 1, "minutes": 30})
return generated_access_token return generated_access_token
@classmethod @classmethod
def update_token_at_redis(cls, token: str, add_payload: Union[CompanyToken, OccupantToken], add_uuid: str): def update_token_at_redis(cls, token: str, add_payload: Union[dict], user_uuid: str):
if already_token_data := RedisActions.get_json(list_keys=[cls.AUTH_TOKEN, token, '*', add_uuid]).first: list_keys = [cls.AUTH_TOKEN, token, "*"]
print("user_uuid", user_uuid, "add_payload", add_payload)
if not user_uuid:
raise ValueError("User UUID not found")
if already_token_data := RedisActions.get_json(list_keys=list_keys).first:
already_token = cls.process_redis_object(already_token_data) already_token = cls.process_redis_object(already_token_data)
if already_token.is_employee and isinstance(add_payload, CompanyToken): if already_token.is_employee:
already_token.selected_company = add_payload already_token.selected_company = add_payload
list_keys = [cls.AUTH_TOKEN, token, str(already_token.user_uu_id), str(add_uuid)] elif already_token.is_occupant:
print('is_employee: ', list_keys)
elif already_token.is_occupant and isinstance(add_payload, OccupantToken):
already_token.selected_occupant = add_payload already_token.selected_occupant = add_payload
list_keys = [cls.AUTH_TOKEN, token, str(already_token.user_uu_id), str(add_uuid)] list_keys = [cls.AUTH_TOKEN, token, str(user_uuid)]
print('is_occupant: ', list_keys) print("already_token", already_token)
result = RedisActions.set_json(list_keys=list_keys, value=already_token.model_dump(), expires={"hours": 1, "minutes": 30}) result = RedisActions.set_json(list_keys=list_keys, value=already_token.model_dump(), expires={"hours": 1, "minutes": 30})
RedisActions.delete(list_keys=[cls.AUTH_TOKEN, token, str(already_token.user_uu_id)])
return result.first return result.first
raise ValueError("Something went wrong") raise ValueError("Something went wrong")

View File

@ -238,9 +238,14 @@ class Build(CrudCollection):
building_types = None building_types = None
for part in self.parts: for part in self.parts:
building_types = {} building_types = {}
build_type = BuildTypes.filter_by_one( build_type = BuildTypes.query.filter(
system=True, id=part.build_part_type_id, db=db_session BuildTypes.id == part.build_part_type_id
).data ).first()
if not build_type:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="There is no building type in this building.",
)
if build_type.type_code in building_types: if build_type.type_code in building_types:
building_types[build_type.type_code]["list"].append(part.part_no) building_types[build_type.type_code]["list"].append(part.part_no)
else: else:
@ -327,9 +332,10 @@ class BuildParts(CrudCollection):
) )
def part_name(self, db): def part_name(self, db):
if build_type := BuildTypes.filter_by_one( BuildTypes.set_session(db)
system=True, id=self.part_type_id, db=db if build_type := BuildTypes.query.filter(
).data: BuildTypes.id == self.part_type_id
).first():
return f"{str(build_type.type_name).upper()} : {str(self.part_no).upper()}" return f"{str(build_type.type_name).upper()} : {str(self.part_no).upper()}"
return f"Undefined:{str(build_type.type_name).upper()}" return f"Undefined:{str(build_type.type_name).upper()}"

View File

@ -415,7 +415,8 @@ class Application2Employee(CrudCollection):
applications = Applications.query.filter(Applications.id.in_([application.application_id for application in active_applications])).all() applications = Applications.query.filter(Applications.id.in_([application.application_id for application in active_applications])).all()
if extra_applications := Application2EmployeeExtra.query.filter(Application2EmployeeExtra.employee_id == employee_id).all(): if extra_applications := Application2EmployeeExtra.query.filter(Application2EmployeeExtra.employee_id == employee_id).all():
applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all() applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all()
applications.extend(applications_extra) if applications_extra:
applications.extend(applications_extra)
applications_dict = {} applications_dict = {}
for application in applications: for application in applications:
if not application.site_url in applications_dict: if not application.site_url in applications_dict:
@ -466,13 +467,6 @@ class Application2Occupant(CrudCollection):
applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all() applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all()
applications.extend(applications_extra) applications.extend(applications_extra)
applications_dict = {} applications_dict = {}
for application in applications:
if not application.site_url in applications_dict:
applications_dict[str(application.site_url)] = str(application.application_code)
else:
ValueError("Duplicate application code found for single endpoint")
applications.extend(applications_extra)
applications_dict = {}
for application in applications: for application in applications:
if not application.site_url in applications_dict: if not application.site_url in applications_dict:
applications_dict[str(application.site_url)] = str(application.application_code) applications_dict[str(application.site_url)] = str(application.application_code)

View File

@ -89,7 +89,7 @@ class OccupantTokenObject(ApplicationToken):
# Occupant Token Object -> Requires selection of the occupant type for a specific build part # Occupant Token Object -> Requires selection of the occupant type for a specific build part
available_occupants: dict = None available_occupants: dict = None
selected_occupant: Optional[OccupantToken] = None # Selected Occupant Type selected_occupant: Optional[dict] = None # Selected Occupant Type
@property @property
def is_employee(self) -> bool: def is_employee(self) -> bool:
@ -109,7 +109,7 @@ class EmployeeTokenObject(ApplicationToken):
duty_id_list: list[int] # List of duty objects duty_id_list: list[int] # List of duty objects
duty_uu_id_list: list[str] # List of duty objects duty_uu_id_list: list[str] # List of duty objects
selected_company: Optional[CompanyToken] = None # Selected Company Object selected_company: Optional[dict] = None # Selected Company Object
@property @property
def is_employee(self) -> bool: def is_employee(self) -> bool:

View File

@ -1,36 +1,52 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). # Occupant Types
## Getting Started Toplantı Başkanı Toplantı Başkanı MT-PRS Toplantı MT
Toplantı Katip Toplantıda tutanak tutan kişi MT-WRT Toplantı MT
Toplantı Katılımcısı Toplantıda sadece katılan kişi MT-ATT Toplantı MT
Toplantı Danışman Toplantıda danışmanlık yapan kişi MT-ADV Toplantı MT
Toplantı Seçilmiş Başkanı Toplantı Seçilmiş Başkanı MT-VPR Toplantı MT
First, run the development server: Daire Sahibi Daire Sahibi FL-OWN Daire FL
Daire Kiracısı Daire Kiracısı FL-TEN Daire FL
Daire Sakini Daire Sakini FL-RES Daire FL
Daire Sakini Vekili Daire Sakini Vekili FL-REP Daire FL
```bash Bina Avukatı Bina Avukatı BU-ATT Bina BU
npm run dev Bina Avukatı Yardımcısı Bina Avukatı Yardımcısı BU-ATA Bina BU
# or Bina Denetmen Yardımcısı Bina Denetmen Yardımcısı BU-SPA Bina BU
yarn dev Bina Denetmeni Bina Denetmeni BU-SPV Bina BU
# or Bina Yönetici Yardımcısı Bina Yönetici Yardımcısı BU-MNA Bina BU
pnpm dev Bina Yöneticisi Bina Yöneticisi BU-MNG Bina BU
# or Bina Muhasabecisi Bina Muhasabecisi BU-ACC Bina BU
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. Proje Lideri Proje Lideri PRJ-LDR Proje PRJ
Proje Sorumlusu Proje Sorumlusu PRJ-RES Proje PRJ
Proje Ekibi Proje Ekibi PRJ-EMP Proje PRJ
Proje Finans Sorumlusu Proje Finans Sorumlusu PRJ-FIN Proje PRJ
Proje Teknik Sorumlusu Proje Teknik Sorumlusu PRJ-TEC Proje PRJ
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. Bina Teknik Sorumlusu Bina Teknik Sorumlusu BU-TEC Bina BU
Bina Teknik Elemanı Bina Teknik Elemanı BU-EMP Bina BU
Bina Teknik Freelancer Bina Teknik Freelancer BU-FLC Bina BU
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. Daire Mülkiyet Vekili Daire Mülkiyet Vekili FL-DEP Daire FL
## Learn More # Employee Types
To learn more about Next.js, take a look at the following resources: General Manager GM0001 General Manager
Business Manager BM0001 Business Manager
IT Manager IT0001 IT Manager
BULK BULK BULK RECORDS OF THE COMPANY
OCCUPANT OCCUPANT OCCUPANT RECORDS OF THE COMPANY
Database Manager DM Database Manager
Network Manager NM Network Manager
Application Manager AM Application Manager
Super User SUE Super User
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! Daire Sakini Vekili Daire Sakini Vekili FL-REP Daire FL
URL Type Tested
/building/accounts/managment/accounts : flat_representative No
## Deploy on Vercel /definitions/identifications/people : flat_tenant No
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

View File

@ -1,6 +1,6 @@
import { import {
getSelectionFromRedis, getSelectionFromRedis,
setSelectionToRedis, setActiveSelectionToRedis,
} from "@/fetchers/custom/context/dash/selection/fetch"; } from "@/fetchers/custom/context/dash/selection/fetch";
import { AuthError } from "@/fetchers/types/context"; import { AuthError } from "@/fetchers/types/context";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
@ -43,7 +43,8 @@ export async function GET() {
export async function POST(request: Request) { export async function POST(request: Request) {
try { try {
const selection = await request.json(); const selection = await request.json();
await setSelectionToRedis(selection); await setActiveSelectionToRedis(selection);
return NextResponse.json({ return NextResponse.json({
status: 200, status: 200,
data: selection || null, data: selection || null,

View File

@ -1,5 +1,5 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { loginViaAccessKeys } from "@/fetchers/custom/login/login"; import { loginViaAccessKeys, initFirstSelection } from "@/fetchers/custom/login/login";
import { loginSchemaEmail } from "@/pages/single/auth/login/schemas"; import { loginSchemaEmail } from "@/pages/single/auth/login/schemas";
export async function POST(req: Request): Promise<NextResponse> { export async function POST(req: Request): Promise<NextResponse> {
@ -20,6 +20,7 @@ export async function POST(req: Request): Promise<NextResponse> {
} }
const userLogin = await loginViaAccessKeys(dataValidated); const userLogin = await loginViaAccessKeys(dataValidated);
await initFirstSelection(userLogin.data?.firstSelection, userLogin.data?.userType);
if (userLogin.status === 200 || userLogin.status === 202) { if (userLogin.status === 200 || userLogin.status === 202) {
return NextResponse.json({ return NextResponse.json({
status: 200, status: 200,

View File

@ -0,0 +1,26 @@
import { NextResponse } from "next/server";
import { logoutActiveSession } from "@/fetchers/custom/login/login";
export async function GET(req: Request): Promise<NextResponse> {
try {
const headers = req.headers;
const userLogin = await logoutActiveSession();
if (userLogin.status === 200 || userLogin.status === 202) {
return NextResponse.json({
status: 200,
message: "Logout successfully completed",
data: userLogin.data,
});
} else {
return NextResponse.json({
status: userLogin.status,
message: "Logout NOT successfully completed",
});
}
} catch (error) {
return NextResponse.json({
status: 401,
message: "Logout NOT successfully completed",
});
}
}

View File

@ -1,9 +1,11 @@
'use client'; 'use client';
import { useRouter } from "next/navigation";
import { FC, useState, useEffect } from "react"; import { FC, useState, useEffect } from "react";
import { HeaderProps } from "@/validations/mutual/dashboard/props"; import { HeaderProps } from "@/validations/mutual/dashboard/props";
import { langGetKey } from "@/lib/langGet"; import { langGetKey } from "@/lib/langGet";
import { LanguageTypes } from "@/validations/mutual/language/validations"; import { LanguageTypes } from "@/validations/mutual/language/validations";
import LanguageSelectionComponent from "@/components/mutual/languageSelection/component"; import LanguageSelectionComponent from "@/components/mutual/languageSelection/component";
import { apiGetFetcher } from "@/lib/fetcher";
const translations = { const translations = {
en: { en: {
@ -34,30 +36,25 @@ const HeaderComponent: FC<HeaderProps> = ({
userData, userLoading, userError, refreshUser, updateUser userData, userLoading, userError, refreshUser, updateUser
}) => { }) => {
const lang = onlineData?.lang as LanguageTypes || 'en'; const lang = onlineData?.lang as LanguageTypes || 'en';
const router = useRouter();
const [activeTab, setActiveTab] = useState('notifications'); const [activeTab, setActiveTab] = useState('notifications');
const [isFullscreen, setIsFullscreen] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => { useEffect(() => {
const handleFullscreenChange = () => { const handleFullscreenChange = () => { setIsFullscreen(!!document.fullscreenElement) };
setIsFullscreen(!!document.fullscreenElement);
};
document.addEventListener('fullscreenchange', handleFullscreenChange); document.addEventListener('fullscreenchange', handleFullscreenChange);
return () => { return () => { document.removeEventListener('fullscreenchange', handleFullscreenChange) };
document.removeEventListener('fullscreenchange', handleFullscreenChange);
};
}, []); }, []);
const toggleFullscreen = () => { const toggleFullscreen = () => {
if (document.fullscreenElement) { if (document.fullscreenElement) { document.exitFullscreen() } else {
document.exitFullscreen(); document.documentElement.requestFullscreen().catch(err => { console.error(`Error attempting to enable fullscreen: ${err.message}`) });
} else {
document.documentElement.requestFullscreen().catch(err => {
console.error(`Error attempting to enable fullscreen: ${err.message}`);
});
} }
}; };
const logoutSession = () => { apiGetFetcher({ url: '/api/login/logout', isNoCache: true }).then((logoutSession) => { router.push('/auth/login') }) }
return ( return (
<div className="py-2 px-6 bg-[#f8f4f3] flex items-center shadow-md shadow-black/5 sticky top-0 left-0 z-30"> <div className="py-2 px-6 bg-[#f8f4f3] flex items-center shadow-md shadow-black/5 sticky top-0 left-0 z-30">
<button type="button" className="text-lg text-gray-900 font-semibold sidebar-toggle"> <button type="button" className="text-lg text-gray-900 font-semibold sidebar-toggle">
@ -187,10 +184,7 @@ const HeaderComponent: FC<HeaderProps> = ({
<a <a
role="menuitem" role="menuitem"
className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50 cursor-pointer" className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50 cursor-pointer"
onClick={(e) => { onClick={logoutSession}
e.preventDefault();
// Handle logout logic here
}}
> >
{langGetKey(translations[lang], 'logout')} {langGetKey(translations[lang], 'logout')}
</a> </a>

View File

@ -1,39 +1,78 @@
'use client'; 'use client';
import { FC, useState } from "react"; import { FC, useState } from "react";
import renderOneClientSelection from "./renderOneClientSelection"; import renderOneClientSelection from "./renderOneClientSelection";
interface ClientSelectionSectionProps { interface ClientSelectionSectionProps {
selectionData: any; selectionData: any;
initialSelectedClient?: any; refreshSelection: () => Promise<void>;
onClientSelect?: (client: any) => void; updateSelection: (newSelection: any) => Promise<boolean>;
} }
const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData, refreshSelection, updateSelection }) => {
selectionData, const [expandedBuilds, setExpandedBuilds] = useState<{ [key: string]: boolean }>({});
initialSelectedClient = null,
onClientSelect if (!selectionData || !selectionData.selectionList) { return null }
}) => { const toggleBuildExpansion = (buildUuid: string) => { setExpandedBuilds(prev => ({ ...prev, [buildUuid]: !prev[buildUuid] })); };
const [selectedClient, setSelectedClient] = useState<any>(initialSelectedClient); const isArray = Array.isArray(selectionData.selectionList);
if (!selectionData || !selectionData.selectionList || selectionData.selectionList.length === 0) { return null }
const handleClientSelection = (client: any) => { setSelectedClient(client); if (onClientSelect) { onClientSelect(client) } };
return ( return (
<div className="mb-3"> <div className="mb-3">
{selectionData.selectionList.map((client: any, index: number) => { {isArray ? (
return ( selectionData.selectionList.map((client: any, index: number) => {
<div return (
key={client.uu_id || client.id || `client-${index}`} <div key={client.uu_id || client.id || `client-${index}`}>
onClick={() => handleClientSelection(client)} {client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
> </div>
{client && renderOneClientSelection({ );
item: client, })
isSelected: selectedClient?.uu_id === client.uu_id, ) : (
onClickHandler: handleClientSelection Object.entries(selectionData.selectionList).map(([buildUuid, buildData]: [string, any]) => {
})} const isExpanded = expandedBuilds[buildUuid] || false;
</div> const selectedBuild = selectionData.selectionList[buildUuid].occupants.filter((client: any) => client.uu_id === selectionData.activeSelection?.uu_id)
); const isSelected = selectedBuild.length > 0;
})} return (
<div key={buildUuid} className="mb-2 border rounded">
{/* Build header - clickable */}
<div
className={`w-full text-xs shadow rounded-lg overflow-hidden mb-2 transition-all cursor-pointer ${isExpanded ? 'border-2 border-blue-500' : ''} hover:shadow-md`}
onClick={() => toggleBuildExpansion(buildUuid)}
>
<div className={`${isExpanded ? 'bg-amber-300' : `${isSelected ? 'bg-blue-400' : 'bg-blue-100'}`} p-2 hover:bg-blue-50 transition-all`}>
<div className="flex items-center">
<div className="w-10 h-10 rounded bg-gray-200 flex items-center justify-center border border-gray-300 mr-2">
<div className="text-gray-500 text-sm font-bold">{buildData.build_name ? buildData.build_name.slice(0, 2).toUpperCase() : 'B'}</div>
</div>
<div className="overflow-hidden">
<h2 className="text-sm font-bold text-gray-800 truncate">{buildData.build_name || buildData.build_no || 'Build'}</h2>
<p className="text-xs text-gray-500 truncate">{buildData.description || `Build #${buildData.build_no || ''}`}</p>
</div>
<div className="ml-auto">
<div className={`${isExpanded ? 'bg-blue-500' : 'bg-gray-300'} rounded-full w-6 h-6 flex items-center justify-center`}>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={isExpanded ? "M19 9l-7 7-7-7" : "M9 5l7 7-7 7"} />
</svg>
</div>
</div>
</div>
</div>
</div>
{/* Occupants list - collapsible */}
{isExpanded && (
<div className="pl-3 p-2 border-t">
{buildData.occupants && Array.isArray(buildData.occupants) ? (
buildData.occupants.map((client: any, index: number) => (
<div key={client.occupant_uu_id || client.part_uu_id || `occupant-${index}`}>
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
</div>
))
) : (<div>No occupants found</div>)}
</div>
)}
</div>
);
})
)}
</div> </div>
); );
}; };

View File

@ -13,26 +13,26 @@ import LoadingContent from "@/components/mutual/loader/component";
const MenuComponent: FC<MenuProps> = ({ const MenuComponent: FC<MenuProps> = ({
activePageUrl, availableApplications, prefix, activePageUrl, availableApplications, prefix,
onlineData, onlineLoading, onlineError, onlineData, onlineLoading, onlineError, refreshOnline, updateOnline,
userData, userLoading, userError, userData, userLoading, userError, refreshUser, updateUser,
selectionData, selectionLoading, selectionError, selectionData, selectionLoading, selectionError, refreshSelection, updateSelection,
menuData, menuLoading, menuError menuData, menuLoading, menuError, refreshMenu, updateMenu
}) => { }) => {
if (menuLoading) { return <MenuLoadingState /> } if (menuLoading) { return <MenuLoadingState /> }
if (menuError) { return <MenuErrorState error={menuError} />; } if (menuError) { return <MenuErrorState error={menuError} />; }
if (availableApplications.length === 0) { return <MenuEmptyState />; } if (availableApplications.length === 0) { return <MenuEmptyState />; }
function handleClientSelection(client: any) { console.log('Client selected:', client) }
const lang = onlineData?.lang as LanguageTypes || 'en'; const lang = onlineData?.lang as LanguageTypes || 'en';
return ( return (
<div className="fixed top-24 p-5 left-0 right-0 w-80 border-emerald-150 border-r-2 overflow-y-auto h-[calc(100vh-6rem)]"> <div className="fixed top-24 p-5 left-0 right-0 w-80 border-emerald-150 border-r-2 overflow-y-auto h-[calc(100vh-6rem)]">
<div className="flex flex-col"> <div className="flex flex-col">
{/* User Profile Section */} {/* User Profile Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}> <Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
<UserProfileSection userData={userData} onlineData={onlineData} /> <UserProfileSection userData={userData} onlineData={onlineData} selectionData={selectionData} />
</Suspense> </Suspense>
{/* Client Selection Section */} {/* Client Selection Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}> <Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
<ClientSelectionSection selectionData={selectionData} initialSelectedClient={selectionData} onClientSelect={handleClientSelection} /> <ClientSelectionSection selectionData={selectionData} refreshSelection={refreshSelection} updateSelection={updateSelection} />
</Suspense> </Suspense>
{/* Menu Items Section */} {/* Menu Items Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}> <Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>

View File

@ -2,32 +2,44 @@
import { FC } from "react"; import { FC } from "react";
import { Briefcase } from "lucide-react"; import { Briefcase } from "lucide-react";
interface Props { interface Props {
item: any; item: any;
isSelected: boolean; selectedItem: any;
onClickHandler: (item: any) => void; refreshSelection: () => Promise<void>;
updateSelection: (newSelection: any) => Promise<boolean>;
} }
const RenderOneClientSelection: FC<Props> = ({ item, isSelected, onClickHandler }) => { const selectFromSelectionList = (item: any, selectedItem: any, updateSelection: (newSelection: any) => Promise<boolean>, refreshSelection: () => Promise<void>) => {
if (isSelected) { const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
if (selectedUUID !== itemUUID) { updateSelection(item); refreshSelection() }
}
const RenderOneClientSelection: FC<Props> = ({ item, selectedItem, updateSelection, refreshSelection }) => {
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
const getDisplayName = () => { if (item.public_name) return item.public_name; if (item.part_name) return item.part_name; return "No Name" };
const getDescription = () => { if (item.duty) return item.duty; if (item.description) return item.description; if (item.code) return item.code; return "" };
const getInitials = () => { const name = getDisplayName(); return name.slice(0, 2) };
if (selectedUUID !== itemUUID) {
return ( return (
<div key={item.uu_id} onClick={() => { onClickHandler(item) }} <div key={itemUUID} onClick={() => { selectFromSelectionList(item, selectedItem, updateSelection, refreshSelection) }}
className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all hover:shadow-md mb-2 cursor-pointer"> className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all hover:shadow-md mb-2 cursor-pointer">
<div className="bg-amber-300 p-2 hover:bg-amber-400 transition-all"> <div className="bg-amber-800 p-2 hover:bg-amber-900 transition-all">
<div className="flex items-center"> <div className="flex items-center">
<div className="mr-2 relative"> <div className="mr-2 relative">
<div className="w-8 h-8 rounded-full bg-amber-400 flex items-center justify-center overflow-hidden border border-white"> <div className="w-8 h-8 rounded-full bg-amber-700 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Company" className="w-full h-full object-cover" />) : {item.avatar ? (<img src={item.avatar} alt="Occupant" className="w-full h-full object-cover" />) :
(<div className="text-white text-xs font-bold">{(item.public_name || "No Name").slice(0, 2)}</div>)} (<div className="text-white text-xs font-bold">{getInitials()}</div>)}
</div> </div>
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-amber-400"> <div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-amber-600">
<Briefcase size={8} className="text-amber-600" /> <Briefcase size={8} className="text-amber-800" />
</div> </div>
</div> </div>
<div className="overflow-hidden"> <div className="overflow-hidden">
<h2 className="text-xs font-bold text-black truncate">{item.public_name} {item.company_type}</h2> <h2 className="text-xs font-bold text-white truncate">{getDisplayName()} {item.company_type || ''}</h2>
<p className="text-xs text-amber-800 truncate">{item.duty}</p> <p className="text-xs text-amber-200 truncate">{getDescription()}</p>
</div> </div>
</div> </div>
</div> </div>
@ -35,21 +47,21 @@ const RenderOneClientSelection: FC<Props> = ({ item, isSelected, onClickHandler
) )
} }
return ( return (
<div key={item.uu_id} className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all mb-2 cursor-pointer"> <div key={itemUUID} className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all mb-2 pointer-events-none opacity-70">
<div className="bg-gray-100 p-2"> <div className="bg-amber-300 p-2">
<div className="flex items-center"> <div className="flex items-center">
<div className="mr-2 relative"> <div className="mr-2 relative">
<div className="w-8 h-8 rounded-full bg-gray-300 flex items-center justify-center overflow-hidden border border-white"> <div className="w-8 h-8 rounded-full bg-gray-400 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Company" className="w-full h-full object-cover" />) : {item.avatar ? (<img src={item.avatar} alt="Occupant" className="w-full h-full object-cover opacity-70" />) :
(<div className="text-white text-xs font-bold">{(item.duty || "No Duty").slice(0, 2)}</div>)} (<div className="text-white text-xs font-bold">{getInitials()}</div>)}
</div> </div>
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-gray-300"> <div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-gray-400">
<Briefcase size={8} className="text-gray-600" /> <Briefcase size={8} className="text-gray-500" />
</div> </div>
</div> </div>
<div className="overflow-hidden"> <div className="overflow-hidden">
<h2 className="text-xs font-bold text-gray-700 truncate">{item.public_name} {item.company_type}</h2> <h2 className="text-xs font-bold text-gray-600 truncate">{getDisplayName()} {item.company_type || ''}</h2>
<p className="text-xs text-gray-600 truncate">{item.duty}</p> <p className="text-xs text-gray-500 truncate">{getDescription()}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,15 +1,29 @@
'use client'; 'use client';
import { FC } from "react"; import { FC } from "react";
import { ClientUser } from "@/types/mutual/context/validations"; import { ClientUser } from "@/types/mutual/context";
import { ClientOnline } from "@/types/mutual/context/validations"; import { ClientOnline } from "@/types/mutual/context";
import { ClientSelection } from "@/types/mutual/context";
interface UserProfileSectionProps { interface UserProfileSectionProps {
userData: ClientUser | null; userData: ClientUser | null;
onlineData: ClientOnline | null; onlineData: ClientOnline | null;
selectionData: ClientSelection;
} }
const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData }) => { const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData, selectionData }) => {
console.log("selectionData", selectionData)
if (!selectionData?.activeSelection) return null;
let selectionDefinitionFirst = "";
let selectionDefinitionSecond = "";
if (selectionData.activeSelection?.description && selectionData.activeSelection?.part_name) {
selectionDefinitionFirst = selectionData?.activeSelection?.description || "No selection";
selectionDefinitionSecond = selectionData?.activeSelection?.part_name || "No selection";
} else {
selectionDefinitionFirst = selectionData?.activeSelection?.public_name || "No selection";
selectionDefinitionSecond = selectionData?.activeSelection?.duty || "No selection";
}
if (!userData) return null; if (!userData) return null;
return ( return (
<div className="mb-2"> <div className="mb-2">
@ -26,7 +40,8 @@ const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData
<div className="overflow-hidden"> <div className="overflow-hidden">
<h2 className="text-sm font-bold text-black truncate">{userData?.person ? `${userData.person.firstname} ${userData.person.surname}` : 'User'}</h2> <h2 className="text-sm font-bold text-black truncate">{userData?.person ? `${userData.person.firstname} ${userData.person.surname}` : 'User'}</h2>
<p className="text-xs text-amber-800 truncate">{userData?.email || 'No email'}</p> <p className="text-xs text-amber-800 truncate">{userData?.email || 'No email'}</p>
<p className="text-xs font-medium capitalize">{onlineData?.userType || 'guest'}</p> <p className="text-xs font-medium capitalize">{selectionDefinitionFirst}</p>
<p className="text-xs font-medium capitalize">{selectionDefinitionSecond || ''}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,6 +3,7 @@ import { redis } from "@/lib/redis";
import { functionRetrieveUserSelection } from "@/fetchers/fecther"; import { functionRetrieveUserSelection } from "@/fetchers/fecther";
import { ClientSelection, AuthError } from "@/fetchers/types/context"; import { ClientSelection, AuthError } from "@/fetchers/types/context";
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch"; import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
import { loginSelectEmployee, loginSelectOccupant } from "@/fetchers/custom/login/login";
const getSelectionFromRedis = async (): Promise<ClientSelection> => { const getSelectionFromRedis = async (): Promise<ClientSelection> => {
try { try {
@ -17,7 +18,7 @@ const getSelectionFromRedis = async (): Promise<ClientSelection> => {
} catch (error) { return { selectionList: [], activeSelection: {} } } } catch (error) { return { selectionList: [], activeSelection: {} } }
} }
const setSelectionToRedis = async (selectionObject: ClientSelection) => { const setActiveSelectionToRedis = async (selectionObject: any) => {
try { try {
const decrpytUserSelection = await functionRetrieveUserSelection() const decrpytUserSelection = await functionRetrieveUserSelection()
if (!decrpytUserSelection) throw new AuthError("No user selection found"); if (!decrpytUserSelection) throw new AuthError("No user selection found");
@ -30,10 +31,19 @@ const setSelectionToRedis = async (selectionObject: ClientSelection) => {
const oldData = await getCompleteFromRedis(); const oldData = await getCompleteFromRedis();
if (!oldData) throw new AuthError("No old data found in redis"); if (!oldData) throw new AuthError("No old data found in redis");
await setCompleteToRedis({ ...oldData, selection: selectionObject }) await setCompleteToRedis({
...oldData, selection: {
selectionList: oldData.selection.selectionList,
activeSelection: selectionObject
}
})
if (oldData.online.userType.toUpperCase() === "EMPLOYEE") {
await loginSelectEmployee({ uuid: selectionObject.uuid });
} else if (oldData.online.userType.toUpperCase() === "OCCUPANT") {
await loginSelectOccupant({ uuid: selectionObject.build_living_space_uu_id });
}
return true; return true;
} catch (error) { } catch (error) {
// Re-throw AuthError instances, wrap other errors as AuthError
if (error instanceof AuthError) { if (error instanceof AuthError) {
throw error; throw error;
} else { } else {
@ -42,4 +52,4 @@ const setSelectionToRedis = async (selectionObject: ClientSelection) => {
} }
} }
export { getSelectionFromRedis, setSelectionToRedis }; export { getSelectionFromRedis, setActiveSelectionToRedis };

View File

@ -15,7 +15,7 @@ import {
import { retrievePageList } from "@/fetchers/mutual/cookies/token"; import { retrievePageList } from "@/fetchers/mutual/cookies/token";
import { deleteAllCookies } from "@/fetchers/mutual/cookies/cookie-actions"; import { deleteAllCookies } from "@/fetchers/mutual/cookies/cookie-actions";
import { setMenuToRedis } from "@/fetchers/custom/context/page/menu/fetch"; import { setMenuToRedis } from "@/fetchers/custom/context/page/menu/fetch";
import { LoginViaAccessKeys, LoginSelect, LoginSelectOccupant } from "@/fetchers/types/login/validations"; import { LoginViaAccessKeys, LoginSelect } from "@/fetchers/types/login/validations";
async function logoutActiveSession() { async function logoutActiveSession() {
const response = await fetchDataWithToken(urlLogoutEndpoint, {}, "GET", false); const response = await fetchDataWithToken(urlLogoutEndpoint, {}, "GET", false);
@ -25,29 +25,50 @@ async function logoutActiveSession() {
async function initRedis(loginRespone: any, firstSelection: any, accessToken: string, redisKey: string) { async function initRedis(loginRespone: any, firstSelection: any, accessToken: string, redisKey: string) {
let alreadyAtRedis = null let alreadyAtRedis = null
try { console.log("loginRespone", loginRespone)
const redisData = await getCompleteFromRedis(); console.log("firstSelection", firstSelection)
alreadyAtRedis = redisData; console.log("accessToken", accessToken)
} catch (error) { } console.log("redisKey", redisKey)
if (!alreadyAtRedis) { if (!alreadyAtRedis) {
const loginObjectToRedis = { if (loginRespone.user_type.toUpperCase() === "EMPLOYEE") {
online: { const loginObjectToRedis = {
...defaultValuesOnline, online: { ...defaultValuesOnline, lastLogin: new Date(), userType: `${loginRespone.user_type}`.toUpperCase(), lang: loginRespone.user.person.country_code.toLowerCase() },
lastLogin: new Date(), pageConfig: defaultValuesPageConfig,
userType: `${loginRespone.user_type}`.toUpperCase(), menu: defaultValuesMenu,
lang: loginRespone.user.person.country_code.toLowerCase(), header: defaultValuesHeader,
}, selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
pageConfig: defaultValuesPageConfig, user: loginRespone.user,
menu: defaultValuesMenu, settings: { lastOnline: new Date(), token: accessToken },
header: defaultValuesHeader, chatRoom: [],
selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection }, notifications: [],
user: loginRespone.user, messages: [],
settings: { lastOnline: new Date(), token: accessToken }, }
chatRoom: [], await setNewCompleteToRedis(loginObjectToRedis, redisKey);
notifications: [], } else if (loginRespone.user_type.toUpperCase() === "OCCUPANT") {
messages: [], const loginObjectToRedis = {
online: { ...defaultValuesOnline, lastLogin: new Date(), userType: `${loginRespone.user_type}`.toUpperCase(), lang: "tr" },
pageConfig: defaultValuesPageConfig,
menu: defaultValuesMenu,
header: defaultValuesHeader,
selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
user: loginRespone.user,
settings: { lastOnline: new Date(), token: accessToken },
chatRoom: [],
notifications: [],
messages: [],
}
await setNewCompleteToRedis(loginObjectToRedis, redisKey);
} }
await setNewCompleteToRedis(loginObjectToRedis, redisKey); }
}
async function initFirstSelection(firstSelection: any, userType: string) {
if (userType === "EMPLOYEE") {
const uuid = firstSelection.uuid;
await loginSelectEmployee({ uuid });
} else if (userType === "OCCUPANT") {
const uuid = firstSelection.build_living_space_uu_id;
await loginSelectOccupant({ uuid });
} }
} }
@ -68,22 +89,24 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
if (response.status === 200 || response.status === 202) { if (response.status === 200 || response.status === 202) {
const loginRespone: any = response?.data; const loginRespone: any = response?.data;
const firstSelection = loginRespone.selection_list.find((item: any) => item.uu_id === loginRespone.selection_list[0].uu_id);
let firstSelection = null
if (loginRespone.user_type.toUpperCase() === "EMPLOYEE") {
firstSelection = loginRespone.selection_list.find((item: any) => item.uu_id === loginRespone.selection_list[0].uu_id);
} else if (loginRespone.user_type.toUpperCase() === "OCCUPANT") {
const firstKeyOfSelectionList = Object.keys(loginRespone.selection_list)[0];
firstSelection = loginRespone.selection_list[firstKeyOfSelectionList].occupants[0];
}
const nextCrypto = new NextCrypto(tokenSecret); const nextCrypto = new NextCrypto(tokenSecret);
const accessToken = await nextCrypto.encrypt(loginRespone.access_token); const accessToken = await nextCrypto.encrypt(loginRespone.access_token);
const userType = loginRespone.user_type.toUpperCase()
const redisKey = `CLIENT:${loginRespone.user_type.toUpperCase()}:${firstSelection.uu_id}`; const redisKey = `CLIENT:${userType}:${loginRespone.user.uuid}`;
const redisKeyAccess = await nextCrypto.encrypt(redisKey); const redisKeyAccess = await nextCrypto.encrypt(redisKey);
const usersSelection = await nextCrypto.encrypt( const usersSelection = await nextCrypto.encrypt(JSON.stringify({ selected: firstSelection, userType, redisKey }));
JSON.stringify({
selected: firstSelection.uu_id,
userType: loginRespone.user_type.toUpperCase(),
redisKey,
})
);
await initRedis(loginRespone, firstSelection, accessToken, redisKey); await initRedis(loginRespone, firstSelection, accessToken, redisKey);
cookieStore.set({ cookieStore.set({
name: "eys-zzz", name: "eys-zzz",
value: accessToken, value: accessToken,
@ -99,12 +122,16 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
value: usersSelection, value: usersSelection,
...cookieObject, ...cookieObject,
}); });
try { try {
return { return {
completed: true, completed: true,
message: "Login successful", message: "Login successful",
status: 200, status: 200,
data: loginRespone, data: {
userType,
firstSelection,
},
}; };
} catch (error) { } catch (error) {
console.error("JSON parse error:", error); console.error("JSON parse error:", error);
@ -112,7 +139,10 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
completed: false, completed: false,
message: "Login NOT successful", message: "Login NOT successful",
status: 401, status: 401,
data: "{}", data: {
userType,
firstSelection,
},
}; };
} }
} }
@ -135,65 +165,32 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
} }
async function loginSelectEmployee(payload: LoginSelect) { async function loginSelectEmployee(payload: LoginSelect) {
const cookieStore = await cookies();
const nextCrypto = new NextCrypto(tokenSecret);
const employeeUUID = payload.uuid; const employeeUUID = payload.uuid;
const redisKey = `CLIENT:EMPLOYEE:${employeeUUID}`;
const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: employeeUUID }, "POST", false); const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: employeeUUID }, "POST", false);
cookieStore.delete({ name: "eys-sel", ...cookieObject }); console.log("selectResponse", selectResponse)
if (selectResponse.status === 200 || selectResponse.status === 202) { if (selectResponse.status === 200 || selectResponse.status === 202) {
const usersSelection = await nextCrypto.encrypt(
JSON.stringify({
selected: employeeUUID,
userType: "employee",
redisKey,
})
);
cookieStore.set({
name: "eys-sel",
value: usersSelection,
...cookieObject,
});
try { try {
const pageList = await retrievePageList() console.log("selectResponse", selectResponse)
await setMenuToRedis({
selectionList: pageList,
activeSelection: "/dashboard"
})
} catch (error) { } } catch (error) { }
} }
return selectResponse; return selectResponse;
} }
async function loginSelectOccupant(payload: LoginSelectOccupant) { async function loginSelectOccupant(payload: LoginSelect) {
const livingSpaceUUID = payload.uuid; const livingSpaceUUID = payload.uuid;
const cookieStore = await cookies();
const nextCrypto = new NextCrypto(tokenSecret);
const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: livingSpaceUUID }, "POST", false); const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: livingSpaceUUID }, "POST", false);
const redisKey = `CLIENT:OCCUPANT:${livingSpaceUUID}`; console.log("selectResponse", selectResponse)
cookieStore.delete("eys-sel");
if (selectResponse.status === 200 || selectResponse.status === 202) { if (selectResponse.status === 200 || selectResponse.status === 202) {
const usersSelection = await nextCrypto.encrypt( try {
JSON.stringify({ console.log("selectResponse", selectResponse)
selected: livingSpaceUUID, } catch (error) { }
userType: "OCCUPANT",
redisKey,
})
);
cookieStore.set({
name: "eys-sel",
value: usersSelection,
...cookieObject,
});
} }
return selectResponse; return selectResponse;
} }
export { export {
loginViaAccessKeys, loginViaAccessKeys,
initFirstSelection,
loginSelectEmployee, loginSelectEmployee,
loginSelectOccupant, loginSelectOccupant,
logoutActiveSession, logoutActiveSession,

View File

@ -8,8 +8,4 @@ interface LoginSelect {
uuid: string; uuid: string;
} }
interface LoginSelectOccupant { export type { LoginViaAccessKeys, LoginSelect };
uuid: any;
}
export type { LoginViaAccessKeys, LoginSelect, LoginSelectOccupant };

View File

@ -1,10 +1,7 @@
import { DashboardPage } from "@/components/custom/content/DashboardPage"; import { DashboardPage } from "@/components/custom/content/DashboardPage";
const pageIndexMulti: Record<string, Record<string, React.FC<any>>> = { const pageIndexMulti: Record<string, Record<string, React.FC<any>>> = {
"/dashboard": { "/dashboard": { DashboardPage: DashboardPage },
DashboardPage: DashboardPage,
},
// Add more pages as needed
}; };
export { pageIndexMulti }; export { pageIndexMulti };