feat(account-setup): enhance localization and UI for account setup process
- Added new language support and improved translations for account setup steps across multiple languages. - Updated the organization step to streamline user input and enhance suggestions for organization names. - Refactored task management components to improve user experience when adding and managing tasks. - Removed outdated CSS for admin center components to simplify styling and improve maintainability. - Introduced new UI elements and transitions for a more engaging account setup experience. - Enhanced Redux state management to accommodate new features and localization updates.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
/* Account Setup Page Styles */
|
||||
|
||||
/* Steps styling - using Ant Design theme tokens */
|
||||
.ant-steps-item-finish .ant-steps-item-icon {
|
||||
border-color: var(--ant-color-primary) !important;
|
||||
@@ -23,12 +25,17 @@
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.ant-steps-item-process .ant-steps-item-icon {
|
||||
border-color: var(--ant-color-primary) !important;
|
||||
background-color: var(--ant-color-primary) !important;
|
||||
color: var(--ant-color-white) !important;
|
||||
}
|
||||
|
||||
.progress-steps .ant-steps-item.ant-steps-item-process .ant-steps-item-title::after {
|
||||
background-color: var(--ant-color-primary) !important;
|
||||
width: 60px !important;
|
||||
}
|
||||
|
||||
/* Steps title styling */
|
||||
.ant-steps-item-title {
|
||||
color: var(--ant-color-text) !important;
|
||||
}
|
||||
@@ -37,7 +44,7 @@
|
||||
color: var(--ant-color-text-secondary) !important;
|
||||
}
|
||||
|
||||
/* Responsive design improvements */
|
||||
/* Responsive layout */
|
||||
@media (max-width: 1000px) {
|
||||
.progress-steps,
|
||||
.step,
|
||||
@@ -72,295 +79,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.organization-name-form,
|
||||
.first-project-form,
|
||||
.create-first-task-form {
|
||||
width: 90% !important;
|
||||
max-width: 500px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.organization-name-form,
|
||||
.first-project-form,
|
||||
.create-first-task-form {
|
||||
width: 95% !important;
|
||||
max-width: 400px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.organization-name-form,
|
||||
.first-project-form,
|
||||
.create-first-task-form {
|
||||
width: 100% !important;
|
||||
max-width: 300px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.vert-text {
|
||||
max-width: 40px;
|
||||
background-color: var(--ant-color-bg-container);
|
||||
color: var(--ant-color-text);
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
margin: 2rem auto;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.vert-line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: var(--ant-color-border);
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
/* Legacy dark mode classes for backward compatibility */
|
||||
.dark-mode .vert-text,
|
||||
.vert-text-dark {
|
||||
background-color: var(--ant-color-bg-container);
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
|
||||
.dark-mode .vert-line,
|
||||
.vert-line-dark {
|
||||
background-color: var(--ant-color-border);
|
||||
}
|
||||
|
||||
/* Button and component improvements */
|
||||
.custom-close-button:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.setup-action-buttons {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.setup-action-buttons .ant-btn {
|
||||
min-height: 40px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Form styling with Ant Design theme tokens */
|
||||
.step-form .ant-form-item-label > label {
|
||||
color: var(--ant-color-text) !important;
|
||||
}
|
||||
|
||||
.step-form .ant-input,
|
||||
.step-form .ant-input-affix-wrapper {
|
||||
background-color: var(--ant-color-bg-container) !important;
|
||||
border-color: var(--ant-color-border) !important;
|
||||
color: var(--ant-color-text) !important;
|
||||
}
|
||||
|
||||
.step-form .ant-input:focus,
|
||||
.step-form .ant-input-affix-wrapper:focus,
|
||||
.step-form .ant-input-affix-wrapper-focused {
|
||||
background-color: var(--ant-color-bg-container) !important;
|
||||
border-color: var(--ant-color-primary) !important;
|
||||
color: var(--ant-color-text) !important;
|
||||
}
|
||||
|
||||
.step-form .ant-input::placeholder {
|
||||
color: var(--ant-color-text-placeholder) !important;
|
||||
}
|
||||
|
||||
/* Select styling */
|
||||
.step-form .ant-select-selector {
|
||||
background-color: var(--ant-color-bg-container) !important;
|
||||
border-color: var(--ant-color-border) !important;
|
||||
color: var(--ant-color-text) !important;
|
||||
}
|
||||
|
||||
.step-form .ant-select-selection-placeholder {
|
||||
color: var(--ant-color-text-placeholder) !important;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
.step-form .ant-typography {
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
|
||||
.step-form .ant-typography.ant-typography-secondary {
|
||||
color: var(--ant-color-text-secondary);
|
||||
}
|
||||
|
||||
/* Card styling */
|
||||
.step-form .ant-card {
|
||||
background-color: var(--ant-color-bg-container);
|
||||
border-color: var(--ant-color-border);
|
||||
}
|
||||
|
||||
.step-form .ant-card-body {
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
|
||||
/* Checkbox and Radio styling */
|
||||
.step-form .ant-checkbox-wrapper {
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
|
||||
.step-form .ant-radio-wrapper {
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
|
||||
/* Smooth transitions for theme switching */
|
||||
* {
|
||||
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
||||
}
|
||||
|
||||
/* Survey step transitions */
|
||||
.survey-page-transition {
|
||||
animation: fadeInUp 0.4s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Survey option hover effects */
|
||||
.survey-option-card {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.survey-option-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Progress bar animation */
|
||||
.ant-progress-line {
|
||||
transition: all 0.5s ease-out;
|
||||
}
|
||||
|
||||
/* Survey button animations */
|
||||
.survey-nav-button {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.survey-nav-button:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* Project step enhancements */
|
||||
.project-suggestion-button {
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.project-suggestion-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.project-suggestion-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.template-preview-card {
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.template-preview-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.template-preview-card.selected {
|
||||
box-shadow: 0 4px 20px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Enhanced form styling for project step */
|
||||
.project-step .ant-input-affix-wrapper {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.project-step .ant-input-affix-wrapper:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
|
||||
.project-step .ant-card {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.project-step .ant-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* Organization step enhancements */
|
||||
.organization-step .ant-input-affix-wrapper {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.organization-step .ant-input-affix-wrapper:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.organization-step .ant-card {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.organization-step .ant-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.organization-suggestion-button {
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.organization-suggestion-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.organization-suggestion-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Character counter styling */
|
||||
.organization-step .character-counter {
|
||||
font-size: 12px;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.organization-step .character-counter.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Naming tips hover effect */
|
||||
.organization-step .naming-tip {
|
||||
transition: all 0.2s ease;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.organization-step .naming-tip:hover {
|
||||
background-color: rgba(24, 144, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Tasks step enhancements */
|
||||
/* Tasks step specific styles */
|
||||
.tasks-step .task-item-card {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@@ -377,47 +96,70 @@
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.task-suggestion-button {
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.task-suggestion-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.task-suggestion-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Members step enhancements */
|
||||
.members-step .member-item-card {
|
||||
/* Project step specific styles */
|
||||
.project-step .ant-input-affix-wrapper {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.members-step .member-item-card:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
.project-step .ant-input-affix-wrapper:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
|
||||
.members-step .member-input {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.members-step .member-input:focus {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.email-suggestion-button {
|
||||
.project-suggestion-button {
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.email-suggestion-button:hover {
|
||||
.project-suggestion-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.email-suggestion-button:active {
|
||||
.project-suggestion-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Organization step specific styles */
|
||||
.organization-step .ant-input-affix-wrapper {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.organization-step .ant-input-affix-wrapper:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.organization-suggestion-button {
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.organization-suggestion-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.organization-suggestion-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Survey step animations */
|
||||
.survey-page-transition {
|
||||
animation: fadeInUp 0.4s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme transitions */
|
||||
* {
|
||||
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Space, Steps, Button, Typography, theme, Dropdown, MenuProps } from '@/shared/antd-imports';
|
||||
import { GlobalOutlined } from '@/shared/antd-imports';
|
||||
import { GlobalOutlined, MoonOutlined, SunOutlined } from '@/shared/antd-imports';
|
||||
|
||||
import logger from '@/utils/errorLogger';
|
||||
import { setCurrentStep, setSurveySubStep } from '@/features/account-setup/account-setup.slice';
|
||||
@@ -33,9 +33,11 @@ import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import './account-setup.css';
|
||||
import { IAccountSetupRequest } from '@/types/project-templates/project-templates.types';
|
||||
import { profileSettingsApiService } from '@/api/settings/profile/profile-settings.api.service';
|
||||
import { projectTemplatesApiService } from '@/api/project-templates/project-templates.api.service';
|
||||
import { surveyApiService } from '@/api/survey/survey.api.service';
|
||||
import { ISurveySubmissionRequest, ISurveyAnswer } from '@/types/account-setup/survey.types';
|
||||
import { setLanguage } from '@/features/i18n/localesSlice';
|
||||
import { toggleTheme } from '@/features/theme/themeSlice';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
@@ -211,6 +213,47 @@ const AccountSetup: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const completeAccountSetupWithTemplate = async () => {
|
||||
try {
|
||||
await saveSurveyData(); // Save survey data first
|
||||
|
||||
const model: IAccountSetupRequest = {
|
||||
team_name: sanitizeInput(organizationName),
|
||||
project_name: null, // No project name when using template
|
||||
template_id: templateId,
|
||||
tasks: [],
|
||||
team_members: [],
|
||||
survey_data: {
|
||||
organization_type: surveyData.organization_type,
|
||||
user_role: surveyData.user_role,
|
||||
main_use_cases: surveyData.main_use_cases,
|
||||
previous_tools: surveyData.previous_tools,
|
||||
how_heard_about: surveyData.how_heard_about,
|
||||
},
|
||||
};
|
||||
|
||||
const res = await projectTemplatesApiService.setupAccount(model);
|
||||
if (res.done && res.body.id) {
|
||||
trackMixpanelEvent(evt_account_setup_complete);
|
||||
|
||||
// Refresh user session to update setup_completed status
|
||||
try {
|
||||
const authResponse = await dispatch(verifyAuthentication()).unwrap() as IAuthorizeResponse;
|
||||
if (authResponse?.authenticated && authResponse?.user) {
|
||||
setSession(authResponse.user);
|
||||
dispatch(setUser(authResponse.user));
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to refresh user session after template setup completion', error);
|
||||
}
|
||||
|
||||
navigate(`/worklenz/projects/${res.body.id}?tab=tasks-list&pinned_tab=tasks-list`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('completeAccountSetupWithTemplate', error);
|
||||
}
|
||||
};
|
||||
|
||||
const steps = [
|
||||
{
|
||||
title: '',
|
||||
@@ -389,6 +432,15 @@ const AccountSetup: React.FC = () => {
|
||||
dispatch(setCurrentStep(currentStep + 1));
|
||||
dispatch(setSurveySubStep(0)); // Reset for next time
|
||||
}
|
||||
} else if (currentStep === 2) {
|
||||
// Project step - check if template is selected
|
||||
if (templateId) {
|
||||
// Template selected, complete account setup with template
|
||||
await completeAccountSetupWithTemplate();
|
||||
} else {
|
||||
// No template, proceed to tasks step
|
||||
dispatch(setCurrentStep(currentStep + 1));
|
||||
}
|
||||
} else if (currentStep === 4) {
|
||||
// Complete setup after members step
|
||||
completeAccountSetup();
|
||||
@@ -412,6 +464,10 @@ const AccountSetup: React.FC = () => {
|
||||
i18n.changeLanguage(languageKey);
|
||||
};
|
||||
|
||||
const handleThemeToggle = () => {
|
||||
dispatch(toggleTheme());
|
||||
};
|
||||
|
||||
const languageMenuItems: MenuProps['items'] = languages.map(lang => ({
|
||||
key: lang.key,
|
||||
label: (
|
||||
@@ -427,11 +483,23 @@ const AccountSetup: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="min-h-screen w-full flex flex-col items-center py-8 px-4 relative"
|
||||
className="account-setup-container min-h-screen w-full flex flex-col items-center py-8 px-4 relative"
|
||||
style={{ backgroundColor: token.colorBgLayout }}
|
||||
>
|
||||
{/* Language Switcher - Top Right */}
|
||||
<div className="absolute top-6 right-6">
|
||||
{/* Controls - Top Right */}
|
||||
<div className="absolute top-6 right-6 flex items-center space-x-3">
|
||||
{/* Theme Switcher */}
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={isDarkMode ? <SunOutlined /> : <MoonOutlined />}
|
||||
onClick={handleThemeToggle}
|
||||
className="flex items-center"
|
||||
style={{ color: token?.colorTextTertiary }}
|
||||
title={isDarkMode ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
/>
|
||||
|
||||
{/* Language Switcher */}
|
||||
<Dropdown
|
||||
menu={{ items: languageMenuItems }}
|
||||
placement="bottomRight"
|
||||
@@ -534,7 +602,6 @@ const AccountSetup: React.FC = () => {
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
disabled={isContinueDisabled()}
|
||||
className="min-h-10 font-medium px-8"
|
||||
onClick={nextStep}
|
||||
>
|
||||
{t('continue')}
|
||||
|
||||
Reference in New Issue
Block a user