Skip to content

Commit

Permalink
feature: added notifications everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
Regikon committed Dec 20, 2024
1 parent 498cd11 commit 8521b8d
Show file tree
Hide file tree
Showing 16 changed files with 175 additions and 59 deletions.
27 changes: 23 additions & 4 deletions src/application/action_creators/cv_action_creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import { FormValue } from '../models/form_value';
import { validateEnglish, validateRequired, validatorTrain } from '../validators/validators';
import { CvFormData, cvStore } from '../stores/cv_store/cv_store';
import { UserType } from '../models/user-type';
import { catch_standard_api_errors } from '../utils/catch_standard_api_errors';
import { notificationActionCreators } from './notification_action_creators';
import { NotificationStyle, NotificationTimeouts } from '../models/notification';

function clearCv() {
storeManager.dispatch({
Expand All @@ -41,7 +44,7 @@ async function loadCv(id: number) {
} as UpdateAction);
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
storeManager.dispatch({
type: CvActions.Update,
payload: {
Expand All @@ -57,9 +60,15 @@ async function removeCv(id: number) {
try {
const token = userStore.getData().csrfToken;
await deleteCv(backendOrigin, token, id);
notificationActionCreators.addNotifications({
text: 'Резюме успешно удалено',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
clearCv();
} catch (err) {
assertIfError(err);
catch_standard_api_errors(err);
console.log(err);
}
}
Expand Down Expand Up @@ -136,9 +145,14 @@ async function createCv(body: CvFormFields) {
loaded: true,
} as UpdateActionPayload,
} as UpdateAction);
notificationActionCreators.addNotifications({
text: 'Резюме успешно создано',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
cvActionCreators.clearCv();
}
}
Expand Down Expand Up @@ -166,9 +180,14 @@ async function updateCv(id: number, body: CvFormFields) {
loaded: true,
} as UpdateActionPayload,
} as UpdateAction);
notificationActionCreators.addNotifications({
text: 'Резюме успешно обновлено',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
}
}

Expand All @@ -186,7 +205,7 @@ async function loadPdf(cvId: number) {
a.click();
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
storeManager.dispatch({
type: CvActions.LoadPdf,
payload: null,
Expand Down
14 changes: 12 additions & 2 deletions src/application/action_creators/profile_action_creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import { UpdateProfilePayload } from '../stores/profile_store/profile_actions';
import { assertIfError } from '@/modules/common_utils/asserts/asserts';
import { makeVacancyFromApi } from '../models/vacancy';
import { makeCvFromApi } from '../models/cv';
import { catch_standard_api_errors } from '../utils/catch_standard_api_errors';
import { notificationActionCreators } from './notification_action_creators';
import { NotificationStyle, NotificationTimeouts } from '../models/notification';

const profileFieldsValidators = new Map(
Object.entries({
Expand Down Expand Up @@ -83,7 +86,7 @@ async function loadProfile(userType: UserType, id: number) {
}
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
clearProfile(true);
}
}
Expand Down Expand Up @@ -169,8 +172,15 @@ async function updateProfile(userType: UserType, body: ProfileFormFields) {
employer.contacts = body.contacts;
userActionCreators.updateProfile(employer);
}
notificationActionCreators.addNotifications({
text: 'Профиль успешно обновлен',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
return true;
} catch {
} catch (err) {
assertIfError(err);
catch_standard_api_errors(err);
return false;
}
}
Expand Down
59 changes: 53 additions & 6 deletions src/application/action_creators/user_action_creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,23 @@ import {
validateOk,
validatePassword,
validateRequired,
validatorTrain,
} from '../validators/validators';
import { storeManager } from '@/modules/store_manager/store_manager';
import { FormValue } from '@/application/models/form_value';
import { getUser } from '@/application/models/utils/get_user';
import { notificationActionCreators } from './notification_action_creators';
import { NotificationStyle, NotificationTimeouts } from '../models/notification';
import { catch_standard_api_errors } from '../utils/catch_standard_api_errors';
import { LoginErrors } from '@/modules/api/src/errors/login/login';
import { RegistrationErrors } from '@/modules/api/src/errors/registration/registration';

function validateLoginData({ userType, email, password }: LoginFormFields): LoginFormData {
const isValid = [userType, email, password].every((field) => field.trim() !== '');
const validatedData = {
userType: validateOk(userType),
email: validateEmail(email),
password: validateOk(password),
email: validatorTrain(validateRequired, validateEmail)(email),
password: validateRequired(password),
isValid,
errorMsg: isValid ? '' : 'Заполните обязательные поля',
};
Expand Down Expand Up @@ -105,13 +111,26 @@ async function login({ userType, email, password }: LoginFormFields) {
email,
password,
});
isAuthorized();
await isAuthorized();
notificationActionCreators.addNotifications({
text: 'Вы успешно вошли в аккаунт',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
console.log(err);
assertIfError(err);
storeManager.dispatch({
type: UserActions.Logout,
} as LogoutAction);
if (err.message === LoginErrors.NoUser) {
notificationActionCreators.addNotifications({
text: 'Пользователь с такой почтой и паролем не найден',
style: NotificationStyle.Error,
timeoutMs: NotificationTimeouts.Medium,
});
return;
}
catch_standard_api_errors(err);
}
}

Expand Down Expand Up @@ -143,7 +162,15 @@ async function logout() {
storeManager.dispatch({
type: UserActions.Logout,
} as LogoutAction);
} catch {}
notificationActionCreators.addNotifications({
text: 'Вы успешно вышли из аккаунта',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
assertIfError(err);
catch_standard_api_errors(err);
}
}

async function register(userType: UserType, body: RegistrationFormFields) {
Expand Down Expand Up @@ -199,6 +226,11 @@ async function register(userType: UserType, body: RegistrationFormFields) {
errorMsg: 'Пароли не совпадают',
} as RegistrationFormData,
});
notificationActionCreators.addNotifications({
text: 'Пароли не совпадают',
style: NotificationStyle.Error,
timeoutMs: NotificationTimeouts.Medium,
});
return;
}

Expand All @@ -225,7 +257,22 @@ async function register(userType: UserType, body: RegistrationFormFields) {
} as registerEmployerOptions);
}
isAuthorized();
} catch {
notificationActionCreators.addNotifications({
text: 'Вы успешно зарегистрировались',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
if (err.message === RegistrationErrors.UserAlreadyExists) {
notificationActionCreators.addNotifications({
text: 'Пользователь с такой почтой уже зарегистрирован',
style: NotificationStyle.Error,
timeoutMs: NotificationTimeouts.Medium,
});
return;
}
assertIfError(err);
catch_standard_api_errors(err);
storeManager.dispatch({
type: UserActions.Logout,
});
Expand Down
39 changes: 28 additions & 11 deletions src/application/action_creators/vacancy_action_creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {
} from '../validators/validators';
import { FormValue } from '../models/form_value';
import { VacancyFormData, vacancyStore } from '../stores/vacancy_store/vacancy_store';
import { notificationActionCreators } from './notification_action_creators';
import { NotificationStyle, NotificationTimeouts } from '../models/notification';
import { catch_standard_api_errors } from '../utils/catch_standard_api_errors';

export interface VacancyFormFields {
position?: string;
Expand Down Expand Up @@ -110,15 +113,19 @@ async function createVacancy(body: VacancyFormFields) {
appliers: [],
} as UpdateActionPayload,
} as UpdateAction);
notificationActionCreators.addNotifications({
text: 'Вакансия успешно создана',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
vacancyActionCreators.clearVacancy();
}
}

async function updateVacancy(id: number, body: VacancyFormFields) {
// const backendOrigin = backendStore.getData().backendOrigin;
if (!validateVacancyForm(body)) {
throw new TypeError('Form is not valid');
}
Expand All @@ -143,9 +150,14 @@ async function updateVacancy(id: number, body: VacancyFormFields) {
appliers: oldVacancy.appliers,
} as UpdateActionPayload,
});
notificationActionCreators.addNotifications({
text: 'Вакансия успешно обновлена',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
}
}

Expand All @@ -172,7 +184,7 @@ async function loadVacancy(id: number) {
} as UpdateAction);
} catch (err) {
assertIfError(err);
console.log(err);
catch_standard_api_errors(err);
storeManager.dispatch({
type: VacancyActions.Update,
payload: {
Expand All @@ -189,9 +201,14 @@ async function removeVacancy(id: number) {
const token = userStore.getData().csrfToken;
await deleteVacancy(backendOrigin, token, id);
clearVacancy();
notificationActionCreators.addNotifications({
text: 'Вакансия успешно удалена',
style: NotificationStyle.Ok,
timeoutMs: NotificationTimeouts.Medium,
});
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -213,8 +230,8 @@ async function loadApplyStatus(vacancyId: number) {
});
}
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -237,8 +254,8 @@ async function loadFavoriteStatus(vacancyId: number) {
});
}
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -251,8 +268,8 @@ async function applyVacancy(vacancyId: number) {
type: VacancyActions.Apply,
});
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -265,8 +282,8 @@ async function addVacancyToFavorite(vacancyId: number) {
type: VacancyActions.AddToFavorite,
});
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -279,8 +296,8 @@ async function removeVacancyFromFavorite(vacancyId: number) {
type: VacancyActions.RemoveFromFavorite,
});
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand All @@ -293,8 +310,8 @@ async function removeApplyVacancy(vacancyId: number) {
type: VacancyActions.ResetApply,
});
} catch (err) {
catch_standard_api_errors(err);
assertIfError(err);
console.log(err);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/application/components/appliers_list/appliers_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export class AppliersList extends Component {
<div className={`${this.props.elementClass} appliers-list`}>
<h1 className="appliers-list__header">Откликнулись</h1>
<div className="appliers-list__divider"></div>
<ol className="appliers-list__list">{...appliersList}</ol>
<ol className="appliers-list__list">
{...appliersList}
{!appliersList || 'Пока никого нет'}
</ol>
</div>
);
}
Expand Down
9 changes: 6 additions & 3 deletions src/application/components/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class Input extends Component {
onFocusOut,
onInput,
error = '',
layout = 'horizontal',
layout = 'vertical',
isValid,
options = [],
maxlength,
Expand Down Expand Up @@ -104,12 +104,15 @@ export class Input extends Component {
className={`input__field ${this.props.isValid !== undefined ? (this.props.isValid ? 'input__field_ok' : 'input__field_error') : ''}`}
name={this.props.name}
id={this.props.id}
value={this.props.value}
onFocusOut={this.props.onFocusOut}
onInput={this.props.onInput}
>
{(this.props.options as Option[]).map((option) => (
<option value={option.value} key={option.value}>
<option
value={option.value}
key={option.value}
selected={this.props.value === option.value}
>
{option.label}
</option>
))}
Expand Down
Loading

0 comments on commit 8521b8d

Please sign in to comment.