Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/app/core/services/workspace.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,13 @@ export function setupWorkspace(workspaceSetupInfo: WorkspaceSetupInfo): Promise<

export async function editWorkspace(
workspaceId: string,
details: { name?: string; description?: string; address?: string },
details: {
name?: string;
description?: string;
address?: string;
phoneNumber?: string | null;
email?: string | null;
},
): Promise<void> {
const workspaceClient = SdkFactory.getNewApiInstance().createWorkspacesClient();
return workspaceClient.editWorkspace(workspaceId, details).catch((error) => {
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,8 @@
"edit": "Profil bearbeiten",
"address": "Adresse",
"phone": "Telefon",
"email": "E-Mail",
"name": "Name",
"owner": "Inhaber",
"workspaceOverview": "Übersicht des Arbeitsbereichs",
"members": "Mitglieder",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@
"edit": "Edit profile",
"address": "Address",
"phone": "Phone",
"email": "Email",
"name": "Name",
"owner": "Owner",
"workspaceOverview": "Workspace overview",
"members": "Members",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,8 @@
"edit": "Editar perfil",
"address": "Dirección",
"phone": "Teléfono",
"email": "Correo",
"name": "Nombre",
"owner": "Propietario",
"workspaceOverview": "Resumen del espacio de trabajo",
"members": "Miembros",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,8 @@
"edit": "Modifier le profil",
"address": "Adresse",
"phone": "Téléphone",
"email": "Email",
"name": "Nom",
"owner": "Propriétaire",
"workspaceOverview": "Vue d'ensemble de l'espace de travail",
"members": "Membres",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@
"edit": "Modifica profilo",
"address": "Indirizzo",
"phone": "Telefono",
"email": "E-mail",
"name": "Nome",
"owner": "Proprietario",
"workspaceOverview": "Panoramica dello spazio di lavoro",
"members": "Membri",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@
"edit": "Редактировать профиль",
"address": "Адрес",
"phone": "Телефон",
"email": "Электронная почта",
"name": "Имя",
"owner": "Владелец",
"workspaceOverview": "Обзор рабочего пространства",
"members": "Участники",
Expand Down
2 changes: 2 additions & 0 deletions src/app/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@
"edit": "编辑个人资料",
"address": "地址",
"phone": "电话",
"email":"电子邮件",
"name": "名字",
"owner": "所有者",
"workspaceOverview": "工作区概览",
"members": "成员",
Expand Down
143 changes: 125 additions & 18 deletions src/app/newSettings/Sections/Workspace/Overview/OverviewSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UserType } from '@internxt/sdk/dist/drive/payments/types';
import { WorkspaceTeam, WorkspaceUser } from '@internxt/sdk/dist/workspaces';
import { Workspace, WorkspaceTeam, WorkspaceUser } from '@internxt/sdk/dist/workspaces';
import { PencilSimple } from '@phosphor-icons/react';
import { t } from 'i18next';
import { useEffect, useState } from 'react';
Expand All @@ -24,6 +24,8 @@ import { getProductCaptions } from '../../../utils/productUtils';
import { getSubscriptionData } from '../../../utils/suscriptionUtils';
import UploadAvatarModal from '../../Account/Account/components/UploadAvatarModal';
import WorkspaceAvatarWrapper from './components/WorkspaceAvatarWrapper';
import { PhoneInput } from 'react-international-phone';
import isValidEmail from '@internxt/lib/dist/src/auth/isValidEmail';

const MIN_NAME_LENGTH = 3;

Expand All @@ -44,13 +46,18 @@ const OverviewSection = ({ onClosePreferences, changeSection }: OverviewSectionP
const workspaceId = selectedWorkspace.workspace.id;
const companyName = selectedWorkspace.workspace.name;
const description = selectedWorkspace.workspace.description;
const phoneNumber = selectedWorkspace.workspace.phoneNumber;
const email = selectedWorkspace.workspace.email;
const avatarSrcURL = selectedWorkspace.workspace.avatar;
const ownerId = selectedWorkspace.workspace.ownerId;
const isOwner = (currentUserId && ownerId && currentUserId === ownerId) || false;

const [isEditingDetails, setIsEditingDetails] = useState(false);
const [editedCompanyName, setEditedCompanyName] = useState(companyName);
const [aboutCompany, setAboutCompany] = useState(description);
const [phoneNumberCompany, setPhoneNumberCompany] = useState(phoneNumber);
const [emailCompany, setEmailCompany] = useState(email);

const [isSavingProfileDetails, setIsSavingProfileDetails] = useState(false);
const [members, setMembers] = useState<WorkspaceUser[] | null>(null);
const [teams, setTeams] = useState<WorkspaceTeam[] | null>(null);
Expand Down Expand Up @@ -108,7 +115,13 @@ const OverviewSection = ({ onClosePreferences, changeSection }: OverviewSectionP
}
};

const onSaveProfileDetails = async (newCompanyName: string, newAboutCompany: string) => {
const onSaveProfileDetails = async (
newCompanyName: string,
newAboutCompany: string,
newPhoneCompany: string | null,
newEmailCompany: string | null,
rollback: () => void,
) => {
setIsSavingProfileDetails(true);
if (newCompanyName.length < MIN_NAME_LENGTH) {
notificationsService.show({
Expand All @@ -118,26 +131,33 @@ const OverviewSection = ({ onClosePreferences, changeSection }: OverviewSectionP
setIsSavingProfileDetails(false);
return;
}

try {
await workspacesService.editWorkspace(workspaceId, {
const payload: Partial<Workspace> = {
name: newCompanyName,
description: newAboutCompany,
});
email: newEmailCompany || null,
...(newPhoneCompany && { phoneNumber: newPhoneCompany }),
};

await workspacesService.editWorkspace(workspaceId, payload);

setEditedCompanyName(newCompanyName);
setAboutCompany(newAboutCompany);
dispatch(
workspacesActions.patchWorkspace({
workspaceId,
patch: {
name: newCompanyName,
description: newAboutCompany,
},
}),
);
setPhoneNumberCompany(newPhoneCompany);
setEmailCompany(newEmailCompany);

dispatch(workspacesActions.patchWorkspace({ workspaceId, patch: payload }));
} catch (error) {
errorService.reportError(error);
const castedError = errorService.castError(error);
notificationsService.show({ type: ToastType.Error, text: castedError.message });

notificationsService.show({
type: ToastType.Error,
text: castedError.message.replace('phoneNumber', 'Phone'),
});

rollback();
} finally {
setIsEditingDetails(false);
setIsSavingProfileDetails(false);
Expand Down Expand Up @@ -174,6 +194,8 @@ const OverviewSection = ({ onClosePreferences, changeSection }: OverviewSectionP
workspaceId={workspaceId}
companyName={editedCompanyName}
description={aboutCompany}
phoneNumber={phoneNumberCompany}
email={emailCompany}
avatarSrcURL={avatarSrcURL}
onEditButtonClick={() => setIsEditingDetails(true)}
isOwner={isOwner}
Expand All @@ -196,6 +218,8 @@ const OverviewSection = ({ onClosePreferences, changeSection }: OverviewSectionP
onClose={() => setIsEditingDetails(false)}
companyName={editedCompanyName}
aboutText={aboutCompany}
phoneNumber={phoneNumberCompany}
email={emailCompany}
onSave={onSaveProfileDetails}
isLoading={isSavingProfileDetails}
/>
Expand All @@ -208,20 +232,58 @@ const EditWorkspaceDetailsModal = ({
onClose,
companyName,
aboutText,
phoneNumber,
email,
onSave,
isLoading,
}: {
isOpen: boolean;
onClose: () => void;
companyName: string;
aboutText: string;
onSave: (editedCompanyName: string, editedAbout: string) => void;
phoneNumber: string | null;
email: string | null;
onSave: (
editedCompanyName: string,
editedAbout: string,
editedPhoneNumber: string | null,
editedEmailCompany: string | null,
rollback: () => void,
) => void;
isLoading: boolean;
}) => {
const MAX_NAME_LENGHT = 50;
const MAX_ABOUT_NAME = 150;
const [editedCompanyName, setEditedCompanyName] = useState(companyName);
const [aboutCompany, setAboutCompany] = useState(aboutText);
const [editedPhoneNumber, setEditedPhoneNumber] = useState(phoneNumber);
const [editedEmailCompany, setEditedEmailCompany] = useState(email || '');
const [blockSubmit, setBlockSubmit] = useState(false);
const [emailAccent, setEmailAccent] = useState<'error' | 'warning' | 'success' | 'default'>('default');

useEffect(() => {
if (!editedEmailCompany || !editedEmailCompany?.length) {
setEmailAccent('default');
setBlockSubmit(false);
return;
}

if (isValidEmail(editedEmailCompany)) {
setEmailAccent('success');
setBlockSubmit(false);
} else {
setEmailAccent('error');
setBlockSubmit(true);
}
}, [editedEmailCompany]);

const handleCancel = () => {
onClose();
setEditedCompanyName(companyName);
setAboutCompany(aboutText);
setEditedPhoneNumber(phoneNumber);
setEditedEmailCompany(email || '');
};

return (
<Modal isOpen={isOpen} onClose={onClose}>
Expand All @@ -231,12 +293,38 @@ const EditWorkspaceDetailsModal = ({
</h1>
<div className="flex grow flex-col space-y-4">
<DetailsInput
label="Name"
label={t('views.preferences.workspace.overview.name')}
textValue={editedCompanyName}
onChangeTextValue={setEditedCompanyName}
maxLength={MAX_NAME_LENGHT}
disabled={isLoading}
hideMaxLength={true}
/>
<DetailsInput
label={t('views.preferences.workspace.overview.email')}
textValue={editedEmailCompany || ''}
variant={'email'}
accent={emailAccent}
placeholder="[email protected]"
onChangeTextValue={setEditedEmailCompany}
disabled={isLoading}
hideMaxLength={true}
/>
<div>
<span className={'text-sm text-gray-80'}>{t('views.preferences.workspace.overview.phone')}</span>
<PhoneInput
value={editedPhoneNumber || ''}
onChange={setEditedPhoneNumber}
inputClassName="!inxt-input !h-10 w-full !rounded-r-md !border !border-gray-20 !bg-transparent !py-1 !px-4 !text-lg !font-normal !text-gray-80 !placeholder-gray-30 !outline-none !ring-primary !ring-opacity-10 !hover:border-gray-30 !focus:border-primary !focus:ring-3 !disabled:border-gray-10 !disabled:text-gray-40 !disabled:placeholder-gray-20 !dark:ring-opacity-20"
countrySelectorStyleProps={{
buttonClassName:
'!h-10 !bg-transparent !px-2 !py-1 !rounded-l-md !border !border-gray-20 !focus:border-primary !focus-visible:border-primary',
}}
disabled={isLoading}
defaultCountry="es"
forceDialCode
/>
</div>
<div>
<textarea
placeholder={aboutCompany}
Expand All @@ -256,10 +344,15 @@ const EditWorkspaceDetailsModal = ({
</div>

<div className="flex w-full flex-row justify-end space-x-2">
<Button disabled={isLoading} variant="secondary" onClick={onClose}>
<Button disabled={isLoading} variant="secondary" onClick={handleCancel}>
{t('views.preferences.workspace.overview.editOverviewDetails.cancelButton')}
</Button>
<Button loading={isLoading} variant="primary" onClick={() => onSave(editedCompanyName, aboutCompany)}>
<Button
loading={isLoading}
disabled={blockSubmit}
variant="primary"
onClick={() => onSave(editedCompanyName, aboutCompany, editedPhoneNumber, editedEmailCompany, handleCancel)}
>
{t('views.preferences.workspace.overview.editOverviewDetails.saveButton')}
</Button>
</div>
Expand Down Expand Up @@ -353,6 +446,8 @@ interface WorkspaceProfileCardProps {
avatarSrcURL: string | null;
companyName: string;
description: string;
phoneNumber: string | null;
email: string | null;
isOwner: boolean;
onEditButtonClick: () => void;
onUploadAvatarClicked: ({ avatar }: { avatar: Blob }) => Promise<void>;
Expand All @@ -364,6 +459,8 @@ const WorkspaceProfileCard: React.FC<WorkspaceProfileCardProps> = ({
avatarSrcURL,
companyName,
description,
phoneNumber,
email,
isOwner,
onEditButtonClick,
onUploadAvatarClicked,
Expand Down Expand Up @@ -422,6 +519,16 @@ const WorkspaceProfileCard: React.FC<WorkspaceProfileCardProps> = ({
)}
</div>

<div className={'mx-5 flex grow flex-col'}>
{phoneNumber && (
<span className={'line-clamp-3 max-w-xs p-1 text-center font-normal leading-4 text-gray-60'}>
{phoneNumber}
</span>
)}
{email && (
<span className={'line-clamp-3 max-w-xs p-1 text-center font-normal leading-4 text-gray-60'}>{email}</span>
)}
</div>
<div className={'mx-5 flex grow flex-col'}>
<span className={'font-semiboldleading-5 max-w-xs truncate text-center text-lg text-gray-100'}>
{companyName}
Expand Down
10 changes: 9 additions & 1 deletion src/app/newSettings/components/DetailsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,32 @@ const DetailsInput = ({
maxLength,
disabled,
hideMaxLength,
variant,
accent,
placeholder,
}: {
label: string;
textValue: string;
onChangeTextValue: (text: string) => void;
maxLength?: number;
hideMaxLength?: boolean;
disabled?: boolean;
variant?: 'default' | 'search' | 'password' | 'email';
accent?: 'default' | 'error' | 'warning' | 'success';
placeholder?: string;
}) => {
return (
<div className="space-y-1">
<Input
label={label}
placeholder={textValue}
placeholder={placeholder}
value={textValue}
disabled={disabled}
className="w-full"
onChange={onChangeTextValue}
maxLength={maxLength}
variant={variant}
accent={accent}
/>
{!hideMaxLength && maxLength && (
<span className="flex w-full justify-end text-sm font-normal leading-4 text-gray-50">
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/components/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function Input({
className?: string;
label?: string;
variant?: 'default' | 'search' | 'password' | 'email';
accent?: 'error' | 'warning' | 'success';
accent?: 'default' | 'error' | 'warning' | 'success';
disabled?: boolean;
placeholder?: string;
value?: string;
Expand Down
Loading