blob: e5da7be28387c17fdc734a8fb8f9cff05f3eaafd [file] [log] [blame]
Ziwei Wang49765ec2023-02-13 16:35:32 -05001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import { Alert, AlertColor, AlertProps, AlertTitle, Snackbar, SnackbarProps } from '@mui/material';
19import { createContext, useCallback, useState } from 'react';
20import { useTranslation } from 'react-i18next';
21
22import { SetState, WithChildren } from '../utils/utils';
23type AlertSnackbarProps = AlertProps & {
24 severity: AlertColor;
25 open?: boolean;
26 snackBarProps?: Partial<SnackbarProps>;
27};
28
29export type AlertContent = {
30 messageI18nKey: AlertMessageKeys;
31 messageI18nContext?: object;
32 severity: AlertColor;
33 alertOpen: boolean;
34};
35
36export function AlertSnackbar({ severity, open, snackBarProps, children, ...alertProps }: AlertSnackbarProps) {
37 const { t } = useTranslation();
38
39 return (
40 <Snackbar
41 open={open}
42 {...snackBarProps}
43 anchorOrigin={{
44 vertical: 'top',
45 horizontal: 'center',
46 ...snackBarProps?.anchorOrigin,
47 }}
48 >
49 <Alert severity={severity} {...alertProps}>
50 <AlertTitle>{t('severity', { context: `${severity}` })}</AlertTitle>
51 {children}
52 </Alert>
53 </Snackbar>
54 );
55}
56
57type IAlertSnackbarContext = {
58 alertContent: AlertContent;
59 setAlertContent: SetState<AlertContent>;
60};
61
62const defaultAlertSnackbarContext: IAlertSnackbarContext = {
63 alertContent: {
64 messageI18nKey: '',
65 messageI18nContext: {},
66 severity: 'info',
67 alertOpen: false,
68 },
69 setAlertContent: () => {},
70};
71
72type AlertMessageKeys =
73 | 'missed_incoming_call'
74 | 'unknown_error_alert'
75 | 'username_input_helper_text_empty'
76 | 'password_input_helper_text_empty'
77 | 'login_invalid_password'
78 | 'registration_success'
79 | '';
80
81export const AlertSnackbarContext = createContext<IAlertSnackbarContext>(defaultAlertSnackbarContext);
82
83const AlertSnackbarProvider = ({ children }: WithChildren) => {
84 const { t } = useTranslation();
85 const [alertContent, setAlertContent] = useState<AlertContent>(defaultAlertSnackbarContext.alertContent);
86 const closeAlert = () => {
87 setAlertContent((prev) => {
88 return {
89 ...prev,
90 alertOpen: false,
91 };
92 });
93 };
94
95 //This is to explicitly let i18n know that these keys should be extracted
96 const getAlertMessageText = useCallback(
97 (messageI18nKey: AlertMessageKeys, messageI18nContext?: object): string => {
98 switch (messageI18nKey) {
99 case 'missed_incoming_call':
100 return t('missed_incoming_call', { ...messageI18nContext });
101 case 'unknown_error_alert':
102 return t('unknown_error_alert');
103 case 'username_input_helper_text_empty':
104 return t('username_input_helper_text_empty');
105 case 'password_input_helper_text_empty':
106 return t('password_input_helper_text_empty');
107 case 'login_invalid_password':
108 return t('login_invalid_password');
109 case 'registration_success':
110 return t('registration_success');
111 default:
112 return t('unknown_error_alert');
113 }
114 },
115 [t]
116 );
117
118 const value = {
119 alertContent,
120 setAlertContent,
121 };
122
123 return (
124 <>
125 <AlertSnackbar severity={alertContent.severity} open={alertContent.alertOpen} onClose={closeAlert}>
126 {getAlertMessageText(alertContent.messageI18nKey, alertContent.messageI18nContext)}
127 </AlertSnackbar>
128 <AlertSnackbarContext.Provider value={value}>{children}</AlertSnackbarContext.Provider>
129 </>
130 );
131};
132
133export default AlertSnackbarProvider;