blob: 028c2c49e93f0b55ba1bca7ae5544a15cc43d729 [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>;
Ziwei Wang45baf532023-02-16 15:41:49 -050060 closeAlert: () => void;
Ziwei Wang49765ec2023-02-13 16:35:32 -050061};
62
63const defaultAlertSnackbarContext: IAlertSnackbarContext = {
64 alertContent: {
65 messageI18nKey: '',
66 messageI18nContext: {},
67 severity: 'info',
68 alertOpen: false,
69 },
70 setAlertContent: () => {},
Ziwei Wang45baf532023-02-16 15:41:49 -050071 closeAlert: () => {},
Ziwei Wang49765ec2023-02-13 16:35:32 -050072};
73
Ziwei Wang3d633dd2023-02-21 16:57:48 -050074//Don't forget to add the cases in the switch statement below
Ziwei Wang49765ec2023-02-13 16:35:32 -050075type AlertMessageKeys =
Ziwei Wang3d633dd2023-02-21 16:57:48 -050076 | 'redirect_admin_setup_complete'
77 | 'password_input_helper_text_invalid'
78 | 'password_input_helper_text_not_match'
79 | 'admin_page_setup_not_complete'
80 | 'admin_page_setup_complete'
Ziwei Wang49765ec2023-02-13 16:35:32 -050081 | 'missed_incoming_call'
82 | 'unknown_error_alert'
83 | 'username_input_helper_text_empty'
84 | 'password_input_helper_text_empty'
85 | 'login_invalid_password'
86 | 'registration_success'
87 | '';
88
89export const AlertSnackbarContext = createContext<IAlertSnackbarContext>(defaultAlertSnackbarContext);
90
91const AlertSnackbarProvider = ({ children }: WithChildren) => {
92 const { t } = useTranslation();
93 const [alertContent, setAlertContent] = useState<AlertContent>(defaultAlertSnackbarContext.alertContent);
94 const closeAlert = () => {
95 setAlertContent((prev) => {
96 return {
97 ...prev,
98 alertOpen: false,
99 };
100 });
101 };
102
103 //This is to explicitly let i18n know that these keys should be extracted
104 const getAlertMessageText = useCallback(
105 (messageI18nKey: AlertMessageKeys, messageI18nContext?: object): string => {
106 switch (messageI18nKey) {
107 case 'missed_incoming_call':
108 return t('missed_incoming_call', { ...messageI18nContext });
109 case 'unknown_error_alert':
110 return t('unknown_error_alert');
111 case 'username_input_helper_text_empty':
112 return t('username_input_helper_text_empty');
113 case 'password_input_helper_text_empty':
114 return t('password_input_helper_text_empty');
115 case 'login_invalid_password':
116 return t('login_invalid_password');
117 case 'registration_success':
118 return t('registration_success');
Ziwei Wang3d633dd2023-02-21 16:57:48 -0500119 case 'redirect_admin_setup_complete':
120 return t('redirect_admin_setup_complete');
121 case 'password_input_helper_text_invalid':
122 return t('password_input_helper_text_invalid');
123 case 'password_input_helper_text_not_match':
124 return t('password_input_helper_text_not_match');
125 case 'admin_page_setup_not_complete':
126 return t('admin_page_setup_not_complete');
127 case 'admin_page_setup_complete':
128 return t('admin_page_setup_complete');
Ziwei Wang49765ec2023-02-13 16:35:32 -0500129 default:
130 return t('unknown_error_alert');
131 }
132 },
133 [t]
134 );
135
136 const value = {
137 alertContent,
138 setAlertContent,
Ziwei Wang45baf532023-02-16 15:41:49 -0500139 closeAlert,
Ziwei Wang49765ec2023-02-13 16:35:32 -0500140 };
141
142 return (
143 <>
144 <AlertSnackbar severity={alertContent.severity} open={alertContent.alertOpen} onClose={closeAlert}>
145 {getAlertMessageText(alertContent.messageI18nKey, alertContent.messageI18nContext)}
146 </AlertSnackbar>
147 <AlertSnackbarContext.Provider value={value}>{children}</AlertSnackbarContext.Provider>
148 </>
149 );
150};
151
152export default AlertSnackbarProvider;