feat(admin-center): implement organization calculation method settings
- Added functionality to update the organization's calculation method (hourly or man-days) in the Admin Center. - Created a new component for managing the calculation method, including UI elements for selection and saving changes. - Updated API service to handle the new endpoint for updating the calculation method. - Enhanced localization files to support new keys related to the calculation method settings. - Introduced a settings page to manage organization working days and hours alongside the calculation method.
This commit is contained in:
@@ -4,5 +4,29 @@
|
||||
"owner": "Pronari i Organizatës",
|
||||
"admins": "Administruesit e Organizatës",
|
||||
"contactNumber": "Shto Numrin e Kontaktit",
|
||||
"edit": "Redakto"
|
||||
"edit": "Redakto",
|
||||
"organizationWorkingDaysAndHours": "Ditët dhe Orët e Punës së Organizatës",
|
||||
"workingDays": "Ditët e Punës",
|
||||
"workingHours": "Orët e Punës",
|
||||
"monday": "E Hënë",
|
||||
"tuesday": "E Martë",
|
||||
"wednesday": "E Mërkurë",
|
||||
"thursday": "E Enjte",
|
||||
"friday": "E Premte",
|
||||
"saturday": "E Shtunë",
|
||||
"sunday": "E Dielë",
|
||||
"hours": "orë",
|
||||
"saveButton": "Ruaj",
|
||||
"saved": "Cilësimet u ruajtën me sukses",
|
||||
"errorSaving": "Gabim gjatë ruajtjes së cilësimeve",
|
||||
"organizationCalculationMethod": "Metoda e Llogaritjes së Organizatës",
|
||||
"calculationMethod": "Metoda e Llogaritjes",
|
||||
"hourlyRates": "Normat Orërore",
|
||||
"manDays": "Ditët e Njeriut",
|
||||
"saveChanges": "Ruaj Ndryshimet",
|
||||
"hourlyCalculationDescription": "Të gjitha kostot e projektit do të llogariten duke përdorur orët e vlerësuara × normat orërore",
|
||||
"manDaysCalculationDescription": "Të gjitha kostot e projektit do të llogariten duke përdorur ditët e vlerësuara të njeriut × normat ditore",
|
||||
"calculationMethodTooltip": "Ky cilësim zbatohet për të gjitha projektet në organizatën tuaj",
|
||||
"calculationMethodUpdated": "Metoda e llogaritjes së organizatës u përditësua me sukses",
|
||||
"calculationMethodUpdateError": "Dështoi përditësimi i metodës së llogaritjes"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "Cilësimet",
|
||||
"organizationWorkingDaysAndHours": "Ditët dhe Orët e Punës së Organizatës",
|
||||
"workingDays": "Ditët e Punës",
|
||||
"workingHours": "Orët e Punës",
|
||||
"hours": "orë",
|
||||
"monday": "E Hënë",
|
||||
"tuesday": "E Martë",
|
||||
"wednesday": "E Mërkurë",
|
||||
"thursday": "E Enjte",
|
||||
"friday": "E Premte",
|
||||
"saturday": "E Shtunë",
|
||||
"sunday": "E Dielë",
|
||||
"saveButton": "Ruaj",
|
||||
"saved": "Cilësimet u ruajtën me sukses",
|
||||
"errorSaving": "Gabim gjatë ruajtjes së cilësimeve"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "Ekipet",
|
||||
"billing": "Faturimi",
|
||||
"projects": "Projektet",
|
||||
"settings": "Cilësimet",
|
||||
"adminCenter": "Qendra Administrative"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,29 @@
|
||||
"owner": "Organisationsinhaber",
|
||||
"admins": "Organisationsadministratoren",
|
||||
"contactNumber": "Kontaktnummer hinzufügen",
|
||||
"edit": "Bearbeiten"
|
||||
"edit": "Bearbeiten",
|
||||
"organizationWorkingDaysAndHours": "Arbeitstage und -stunden der Organisation",
|
||||
"workingDays": "Arbeitstage",
|
||||
"workingHours": "Arbeitsstunden",
|
||||
"monday": "Montag",
|
||||
"tuesday": "Dienstag",
|
||||
"wednesday": "Mittwoch",
|
||||
"thursday": "Donnerstag",
|
||||
"friday": "Freitag",
|
||||
"saturday": "Samstag",
|
||||
"sunday": "Sonntag",
|
||||
"hours": "Stunden",
|
||||
"saveButton": "Speichern",
|
||||
"saved": "Einstellungen erfolgreich gespeichert",
|
||||
"errorSaving": "Fehler beim Speichern der Einstellungen",
|
||||
"organizationCalculationMethod": "Organisations-Berechnungsmethode",
|
||||
"calculationMethod": "Berechnungsmethode",
|
||||
"hourlyRates": "Stundensätze",
|
||||
"manDays": "Mann-Tage",
|
||||
"saveChanges": "Änderungen speichern",
|
||||
"hourlyCalculationDescription": "Alle Projektkosten werden anhand geschätzter Stunden × Stundensätze berechnet",
|
||||
"manDaysCalculationDescription": "Alle Projektkosten werden anhand geschätzter Mann-Tage × Tagessätze berechnet",
|
||||
"calculationMethodTooltip": "Diese Einstellung gilt für alle Projekte in Ihrer Organisation",
|
||||
"calculationMethodUpdated": "Organisations-Berechnungsmethode erfolgreich aktualisiert",
|
||||
"calculationMethodUpdateError": "Fehler beim Aktualisieren der Berechnungsmethode"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "Einstellungen",
|
||||
"organizationWorkingDaysAndHours": "Arbeitstage und -stunden der Organisation",
|
||||
"workingDays": "Arbeitstage",
|
||||
"workingHours": "Arbeitsstunden",
|
||||
"hours": "Stunden",
|
||||
"monday": "Montag",
|
||||
"tuesday": "Dienstag",
|
||||
"wednesday": "Mittwoch",
|
||||
"thursday": "Donnerstag",
|
||||
"friday": "Freitag",
|
||||
"saturday": "Samstag",
|
||||
"sunday": "Sonntag",
|
||||
"saveButton": "Speichern",
|
||||
"saved": "Einstellungen erfolgreich gespeichert",
|
||||
"errorSaving": "Fehler beim Speichern der Einstellungen"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "Teams",
|
||||
"billing": "Abrechnung",
|
||||
"projects": "Projekte",
|
||||
"settings": "Einstellungen",
|
||||
"adminCenter": "Admin-Center"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,29 @@
|
||||
"owner": "Organization Owner",
|
||||
"admins": "Organization Admins",
|
||||
"contactNumber": "Add Contact Number",
|
||||
"edit": "Edit"
|
||||
"edit": "Edit",
|
||||
"organizationWorkingDaysAndHours": "Organization Working Days & Hours",
|
||||
"workingDays": "Working Days",
|
||||
"workingHours": "Working Hours",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"hours": "hours",
|
||||
"saveButton": "Save",
|
||||
"saved": "Settings saved successfully",
|
||||
"errorSaving": "Error saving settings",
|
||||
"organizationCalculationMethod": "Organization Calculation Method",
|
||||
"calculationMethod": "Calculation Method",
|
||||
"hourlyRates": "Hourly Rates",
|
||||
"manDays": "Man Days",
|
||||
"saveChanges": "Save Changes",
|
||||
"hourlyCalculationDescription": "All project costs will be calculated using estimated hours × hourly rates",
|
||||
"manDaysCalculationDescription": "All project costs will be calculated using estimated man days × daily rates",
|
||||
"calculationMethodTooltip": "This setting applies to all projects in your organization",
|
||||
"calculationMethodUpdated": "Organization calculation method updated successfully",
|
||||
"calculationMethodUpdateError": "Failed to update calculation method"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "Settings",
|
||||
"organizationWorkingDaysAndHours": "Organization Working Days & Hours",
|
||||
"workingDays": "Working Days",
|
||||
"workingHours": "Working Hours",
|
||||
"hours": "hours",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"saveButton": "Save",
|
||||
"saved": "Settings saved successfully",
|
||||
"errorSaving": "Error saving settings"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "Teams",
|
||||
"billing": "Billing",
|
||||
"projects": "Projects",
|
||||
"settings": "Settings",
|
||||
"adminCenter": "Admin Center"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,29 @@
|
||||
"owner": "Propietario de la Organización",
|
||||
"admins": "Administradores de la Organización",
|
||||
"contactNumber": "Agregar Número de Contacto",
|
||||
"edit": "Editar"
|
||||
"edit": "Editar",
|
||||
"organizationWorkingDaysAndHours": "Días y Horas Laborales de la Organización",
|
||||
"workingDays": "Días Laborales",
|
||||
"workingHours": "Horas Laborales",
|
||||
"monday": "Lunes",
|
||||
"tuesday": "Martes",
|
||||
"wednesday": "Miércoles",
|
||||
"thursday": "Jueves",
|
||||
"friday": "Viernes",
|
||||
"saturday": "Sábado",
|
||||
"sunday": "Domingo",
|
||||
"hours": "horas",
|
||||
"saveButton": "Guardar",
|
||||
"saved": "Configuración guardada exitosamente",
|
||||
"errorSaving": "Error al guardar la configuración",
|
||||
"organizationCalculationMethod": "Método de Cálculo de la Organización",
|
||||
"calculationMethod": "Método de Cálculo",
|
||||
"hourlyRates": "Tarifas por Hora",
|
||||
"manDays": "Días Hombre",
|
||||
"saveChanges": "Guardar Cambios",
|
||||
"hourlyCalculationDescription": "Todos los costos del proyecto se calcularán usando horas estimadas × tarifas por hora",
|
||||
"manDaysCalculationDescription": "Todos los costos del proyecto se calcularán usando días hombre estimados × tarifas diarias",
|
||||
"calculationMethodTooltip": "Esta configuración se aplica a todos los proyectos en su organización",
|
||||
"calculationMethodUpdated": "Método de cálculo de la organización actualizado exitosamente",
|
||||
"calculationMethodUpdateError": "Error al actualizar el método de cálculo"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "Configuración",
|
||||
"organizationWorkingDaysAndHours": "Días y Horas Laborales de la Organización",
|
||||
"workingDays": "Días Laborales",
|
||||
"workingHours": "Horas Laborales",
|
||||
"hours": "horas",
|
||||
"monday": "Lunes",
|
||||
"tuesday": "Martes",
|
||||
"wednesday": "Miércoles",
|
||||
"thursday": "Jueves",
|
||||
"friday": "Viernes",
|
||||
"saturday": "Sábado",
|
||||
"sunday": "Domingo",
|
||||
"saveButton": "Guardar",
|
||||
"saved": "Configuración guardada exitosamente",
|
||||
"errorSaving": "Error al guardar la configuración"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "Equipos",
|
||||
"billing": "Facturación",
|
||||
"projects": "Proyectos",
|
||||
"settings": "Configuración",
|
||||
"adminCenter": "Centro de Administración"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,29 @@
|
||||
"owner": "Proprietário da Organização",
|
||||
"admins": "Administradores da Organização",
|
||||
"contactNumber": "Adicione o Número de Contato",
|
||||
"edit": "Editar"
|
||||
"edit": "Editar",
|
||||
"organizationWorkingDaysAndHours": "Dias e Horas de Trabalho da Organização",
|
||||
"workingDays": "Dias de Trabalho",
|
||||
"workingHours": "Horas de Trabalho",
|
||||
"monday": "Segunda-feira",
|
||||
"tuesday": "Terça-feira",
|
||||
"wednesday": "Quarta-feira",
|
||||
"thursday": "Quinta-feira",
|
||||
"friday": "Sexta-feira",
|
||||
"saturday": "Sábado",
|
||||
"sunday": "Domingo",
|
||||
"hours": "horas",
|
||||
"saveButton": "Salvar",
|
||||
"saved": "Configurações salvas com sucesso",
|
||||
"errorSaving": "Erro ao salvar configurações",
|
||||
"organizationCalculationMethod": "Método de Cálculo da Organização",
|
||||
"calculationMethod": "Método de Cálculo",
|
||||
"hourlyRates": "Taxas por Hora",
|
||||
"manDays": "Dias Homem",
|
||||
"saveChanges": "Salvar Alterações",
|
||||
"hourlyCalculationDescription": "Todos os custos do projeto serão calculados usando horas estimadas × taxas por hora",
|
||||
"manDaysCalculationDescription": "Todos os custos do projeto serão calculados usando dias homem estimados × taxas diárias",
|
||||
"calculationMethodTooltip": "Esta configuração se aplica a todos os projetos em sua organização",
|
||||
"calculationMethodUpdated": "Método de cálculo da organização atualizado com sucesso",
|
||||
"calculationMethodUpdateError": "Erro ao atualizar o método de cálculo"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "Configurações",
|
||||
"organizationWorkingDaysAndHours": "Dias e Horas de Trabalho da Organização",
|
||||
"workingDays": "Dias de Trabalho",
|
||||
"workingHours": "Horas de Trabalho",
|
||||
"hours": "horas",
|
||||
"monday": "Segunda-feira",
|
||||
"tuesday": "Terça-feira",
|
||||
"wednesday": "Quarta-feira",
|
||||
"thursday": "Quinta-feira",
|
||||
"friday": "Sexta-feira",
|
||||
"saturday": "Sábado",
|
||||
"sunday": "Domingo",
|
||||
"saveButton": "Salvar",
|
||||
"saved": "Configurações salvas com sucesso",
|
||||
"errorSaving": "Erro ao salvar configurações"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "Equipes",
|
||||
"billing": "Faturamento",
|
||||
"projects": "Projetos",
|
||||
"settings": "Configurações",
|
||||
"adminCenter": "Central Administrativa"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,29 @@
|
||||
"owner": "组织所有者",
|
||||
"admins": "组织管理员",
|
||||
"contactNumber": "添加联系电话",
|
||||
"edit": "编辑"
|
||||
"edit": "编辑",
|
||||
"organizationWorkingDaysAndHours": "组织工作日和工作时间",
|
||||
"workingDays": "工作日",
|
||||
"workingHours": "工作时间",
|
||||
"monday": "星期一",
|
||||
"tuesday": "星期二",
|
||||
"wednesday": "星期三",
|
||||
"thursday": "星期四",
|
||||
"friday": "星期五",
|
||||
"saturday": "星期六",
|
||||
"sunday": "星期日",
|
||||
"hours": "小时",
|
||||
"saveButton": "保存",
|
||||
"saved": "设置保存成功",
|
||||
"errorSaving": "保存设置时出错",
|
||||
"organizationCalculationMethod": "组织计算方法",
|
||||
"calculationMethod": "计算方法",
|
||||
"hourlyRates": "小时费率",
|
||||
"manDays": "人天",
|
||||
"saveChanges": "保存更改",
|
||||
"hourlyCalculationDescription": "所有项目成本将使用估算小时数 × 小时费率计算",
|
||||
"manDaysCalculationDescription": "所有项目成本将使用估算人天数 × 日费率计算",
|
||||
"calculationMethodTooltip": "此设置适用于您组织中的所有项目",
|
||||
"calculationMethodUpdated": "组织计算方法更新成功",
|
||||
"calculationMethodUpdateError": "更新计算方法失败"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"settings": "设置",
|
||||
"organizationWorkingDaysAndHours": "组织工作日和工作时间",
|
||||
"workingDays": "工作日",
|
||||
"workingHours": "工作时间",
|
||||
"hours": "小时",
|
||||
"monday": "星期一",
|
||||
"tuesday": "星期二",
|
||||
"wednesday": "星期三",
|
||||
"thursday": "星期四",
|
||||
"friday": "星期五",
|
||||
"saturday": "星期六",
|
||||
"sunday": "星期日",
|
||||
"saveButton": "保存",
|
||||
"saved": "设置保存成功",
|
||||
"errorSaving": "保存设置时出错"
|
||||
}
|
||||
@@ -4,5 +4,6 @@
|
||||
"teams": "团队",
|
||||
"billing": "账单",
|
||||
"projects": "项目",
|
||||
"settings": "设置",
|
||||
"adminCenter": "管理中心"
|
||||
}
|
||||
@@ -280,4 +280,16 @@ export const adminCenterApiService = {
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async updateOrganizationCalculationMethod(
|
||||
calculationMethod: 'hourly' | 'man_days'
|
||||
): Promise<IServerResponse<any>> {
|
||||
const response = await apiClient.put<IServerResponse<any>>(
|
||||
`${rootUrl}/organization/calculation-method`,
|
||||
{
|
||||
calculation_method: calculationMethod,
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Select, Space, Typography, Tooltip, message, Button } from '@/shared/antd-imports';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { InfoCircleOutlined, CalculatorOutlined, SaveOutlined } from '@ant-design/icons';
|
||||
import { adminCenterApiService } from '@/api/admin-center/admin-center.api.service';
|
||||
import { IOrganization } from '@/types/admin-center/admin-center.types';
|
||||
|
||||
const { Option } = Select;
|
||||
const { Text, Title } = Typography;
|
||||
|
||||
interface OrganizationCalculationMethodProps {
|
||||
organization: IOrganization | null;
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
const OrganizationCalculationMethod: React.FC<OrganizationCalculationMethodProps> = ({
|
||||
organization,
|
||||
refetch
|
||||
}) => {
|
||||
const { t } = useTranslation('admin-center/overview');
|
||||
const [updating, setUpdating] = useState(false);
|
||||
const [currentMethod, setCurrentMethod] = useState<'hourly' | 'man_days'>(
|
||||
organization?.calculation_method || 'hourly'
|
||||
);
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (organization) {
|
||||
setCurrentMethod(organization.calculation_method || 'hourly');
|
||||
setHasChanges(false);
|
||||
}
|
||||
}, [organization]);
|
||||
|
||||
const handleMethodChange = (newMethod: 'hourly' | 'man_days') => {
|
||||
setCurrentMethod(newMethod);
|
||||
setHasChanges(newMethod !== organization?.calculation_method);
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
setUpdating(true);
|
||||
try {
|
||||
await adminCenterApiService.updateOrganizationCalculationMethod(currentMethod);
|
||||
|
||||
message.success(t('calculationMethodUpdated'));
|
||||
|
||||
setHasChanges(false);
|
||||
refetch();
|
||||
} catch (error) {
|
||||
console.error('Failed to update organization calculation method:', error);
|
||||
message.error(t('calculationMethodUpdateError'));
|
||||
} finally {
|
||||
setUpdating(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<Space direction="vertical" size="large" style={{ width: '100%' }}>
|
||||
<Space align="center">
|
||||
<CalculatorOutlined />
|
||||
<Title level={5} style={{ margin: 0 }}>
|
||||
{t('organizationCalculationMethod')}
|
||||
</Title>
|
||||
<Tooltip title={t('calculationMethodTooltip')}>
|
||||
<InfoCircleOutlined style={{ color: '#666' }} />
|
||||
</Tooltip>
|
||||
</Space>
|
||||
|
||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||
<Space align="center" wrap>
|
||||
<Text strong>{t('calculationMethod')}:</Text>
|
||||
<Select
|
||||
value={currentMethod}
|
||||
onChange={handleMethodChange}
|
||||
disabled={updating}
|
||||
style={{ width: 150 }}
|
||||
>
|
||||
<Option value="hourly">
|
||||
<Space>
|
||||
<span>{t('hourlyRates')}</span>
|
||||
</Space>
|
||||
</Option>
|
||||
<Option value="man_days">
|
||||
<Space>
|
||||
<span>{t('manDays')}</span>
|
||||
</Space>
|
||||
</Option>
|
||||
</Select>
|
||||
|
||||
{hasChanges && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<SaveOutlined />}
|
||||
onClick={handleSave}
|
||||
loading={updating}
|
||||
size="small"
|
||||
>
|
||||
{t('saveChanges')}
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
|
||||
{currentMethod === 'hourly' && (
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
{t('hourlyCalculationDescription')}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{currentMethod === 'man_days' && (
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>
|
||||
{t('manDaysCalculationDescription')} ({organization?.hours_per_day}h/day)
|
||||
</Text>
|
||||
)}
|
||||
</Space>
|
||||
</Space>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrganizationCalculationMethod;
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
ProfileOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
SettingOutlined,
|
||||
} from '@/shared/antd-imports';
|
||||
import React, { ReactNode, lazy } from 'react';
|
||||
const Overview = lazy(() => import('./overview/overview'));
|
||||
@@ -11,6 +12,7 @@ const Users = lazy(() => import('./users/users'));
|
||||
const Teams = lazy(() => import('./teams/teams'));
|
||||
const Billing = lazy(() => import('./billing/billing'));
|
||||
const Projects = lazy(() => import('./projects/projects'));
|
||||
const Settings = lazy(() => import('./settings/settings'));
|
||||
|
||||
// type of a menu item in admin center sidebar
|
||||
type AdminCenterMenuItems = {
|
||||
@@ -57,4 +59,11 @@ export const adminCenterItems: AdminCenterMenuItems[] = [
|
||||
icon: React.createElement(CreditCardOutlined),
|
||||
element: React.createElement(Billing),
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
name: 'settings',
|
||||
endpoint: 'settings',
|
||||
icon: React.createElement(SettingOutlined),
|
||||
element: React.createElement(Settings),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { EditOutlined, MailOutlined, PhoneOutlined } from '@/shared/antd-imports';
|
||||
import { PageHeader } from '@ant-design/pro-components';
|
||||
import { Button, Card, Input, Space, Tooltip, Typography } from '@/shared/antd-imports';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Card,
|
||||
Space,
|
||||
Typography,
|
||||
} from '@/shared/antd-imports';
|
||||
import { PageHeader } from '@ant-design/pro-components';
|
||||
import OrganizationAdminsTable from '@/components/admin-center/overview/organization-admins-table/organization-admins-table';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { RootState } from '@/app/store';
|
||||
@@ -11,9 +14,6 @@ import OrganizationOwner from '@/components/admin-center/overview/organization-o
|
||||
import { adminCenterApiService } from '@/api/admin-center/admin-center.api.service';
|
||||
import { IOrganization, IOrganizationAdmin } from '@/types/admin-center/admin-center.types';
|
||||
import logger from '@/utils/errorLogger';
|
||||
import { tr } from 'date-fns/locale';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const Overview: React.FC = () => {
|
||||
const [organization, setOrganization] = useState<IOrganization | null>(null);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './settings';
|
||||
156
worklenz-frontend/src/pages/admin-center/settings/settings.tsx
Normal file
156
worklenz-frontend/src/pages/admin-center/settings/settings.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Input,
|
||||
Space,
|
||||
Typography,
|
||||
Checkbox,
|
||||
Col,
|
||||
Form,
|
||||
Row,
|
||||
message,
|
||||
} from '@/shared/antd-imports';
|
||||
import { PageHeader } from '@ant-design/pro-components';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { adminCenterApiService } from '@/api/admin-center/admin-center.api.service';
|
||||
import { IOrganization } from '@/types/admin-center/admin-center.types';
|
||||
import logger from '@/utils/errorLogger';
|
||||
import { scheduleAPIService } from '@/api/schedule/schedule.api.service';
|
||||
import { Settings } from '@/types/schedule/schedule-v2.types';
|
||||
import OrganizationCalculationMethod from '@/components/admin-center/overview/organization-calculation-method/organization-calculation-method';
|
||||
|
||||
const SettingsPage: React.FC = () => {
|
||||
const [organization, setOrganization] = useState<IOrganization | null>(null);
|
||||
const [workingDays, setWorkingDays] = useState<Settings['workingDays']>([]);
|
||||
const [workingHours, setWorkingHours] = useState<Settings['workingHours']>(8);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { t } = useTranslation('admin-center/settings');
|
||||
|
||||
const getOrganizationDetails = async () => {
|
||||
try {
|
||||
const res = await adminCenterApiService.getOrganizationDetails();
|
||||
if (res.done) {
|
||||
setOrganization(res.body);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error getting organization details', error);
|
||||
}
|
||||
};
|
||||
|
||||
const getOrgWorkingSettings = async () => {
|
||||
try {
|
||||
const res = await scheduleAPIService.fetchScheduleSettings();
|
||||
if (res && res.done) {
|
||||
setWorkingDays(
|
||||
res.body.workingDays || ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
|
||||
);
|
||||
setWorkingHours(res.body.workingHours || 8);
|
||||
form.setFieldsValue({
|
||||
workingDays: res.body.workingDays || [
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday',
|
||||
],
|
||||
workingHours: res.body.workingHours || 8,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error getting organization working settings', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = async (values: any) => {
|
||||
setSaving(true);
|
||||
try {
|
||||
const res = await scheduleAPIService.updateScheduleSettings({
|
||||
workingDays: values.workingDays,
|
||||
workingHours: values.workingHours,
|
||||
});
|
||||
if (res && res.done) {
|
||||
message.success(t('saved'));
|
||||
setWorkingDays(values.workingDays);
|
||||
setWorkingHours(values.workingHours);
|
||||
getOrgWorkingSettings();
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error updating organization working days/hours', error);
|
||||
message.error(t('errorSaving'));
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getOrganizationDetails();
|
||||
getOrgWorkingSettings();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ width: '100%' }}>
|
||||
<PageHeader title={<span>{t('settings')}</span>} style={{ padding: '16px 0' }} />
|
||||
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={22}>
|
||||
<Card>
|
||||
<Typography.Title level={5} style={{ margin: 0 }}>
|
||||
{t('organizationWorkingDaysAndHours') || 'Organization Working Days & Hours'}
|
||||
</Typography.Title>
|
||||
<Form
|
||||
layout="vertical"
|
||||
form={form}
|
||||
initialValues={{ workingDays, workingHours }}
|
||||
onFinish={handleSave}
|
||||
style={{ marginTop: 16 }}
|
||||
>
|
||||
<Form.Item label={t('workingDays')} name="workingDays">
|
||||
<Checkbox.Group>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Monday">{t('monday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Tuesday">{t('tuesday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Wednesday">{t('wednesday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Thursday">{t('thursday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Friday">{t('friday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Saturday">{t('saturday')}</Checkbox>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Checkbox value="Sunday">{t('sunday')}</Checkbox>
|
||||
</Col>
|
||||
</Row>
|
||||
</Checkbox.Group>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('workingHours')} name="workingHours">
|
||||
<Input type="number" min={1} max={24} suffix={t('hours')} width={100} />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={saving}>
|
||||
{t('saveButton') || 'Save'}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Card>
|
||||
|
||||
<OrganizationCalculationMethod
|
||||
organization={organization}
|
||||
refetch={getOrganizationDetails}
|
||||
/>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsPage;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ISUBSCRIPTION_TYPE } from '@/shared/constants';
|
||||
import { ISUBSCRIPTION_TYPE } from "@/shared/constants";
|
||||
|
||||
export interface IOrganization {
|
||||
name?: string;
|
||||
@@ -6,6 +6,8 @@ export interface IOrganization {
|
||||
email?: string;
|
||||
contact_number?: string;
|
||||
contact_number_secondary?: string;
|
||||
calculation_method?: 'hourly' | 'man_days';
|
||||
hours_per_day?: number;
|
||||
}
|
||||
|
||||
export interface IOrganizationAdmin {
|
||||
@@ -79,7 +81,6 @@ export interface IBillingAccountInfo {
|
||||
unit_price?: number;
|
||||
unit_price_per_month?: number;
|
||||
usedPercentage?: number;
|
||||
used_percent?: number;
|
||||
usedStorage?: number;
|
||||
is_custom?: boolean;
|
||||
is_ltd_user?: boolean;
|
||||
@@ -230,4 +231,4 @@ export interface IFreePlanSettings {
|
||||
export interface IOrganizationProjectsGetResponse {
|
||||
total?: number;
|
||||
data?: IOrganizationProject[];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user