blob: ac93c6b6608699c1c28a8ebb3db2de2ba2614b3b [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
74type AlertMessageKeys =
75 | 'missed_incoming_call'
76 | 'unknown_error_alert'
77 | 'username_input_helper_text_empty'
78 | 'password_input_helper_text_empty'
79 | 'login_invalid_password'
80 | 'registration_success'
81 | '';
82
83export const AlertSnackbarContext = createContext<IAlertSnackbarContext>(defaultAlertSnackbarContext);
84
85const AlertSnackbarProvider = ({ children }: WithChildren) => {
86 const { t } = useTranslation();
87 const [alertContent, setAlertContent] = useState<AlertContent>(defaultAlertSnackbarContext.alertContent);
88 const closeAlert = () => {
89 setAlertContent((prev) => {
90 return {
91 ...prev,
92 alertOpen: false,
93 };
94 });
95 };
96
97 //This is to explicitly let i18n know that these keys should be extracted
98 const getAlertMessageText = useCallback(
99 (messageI18nKey: AlertMessageKeys, messageI18nContext?: object): string => {
100 switch (messageI18nKey) {
101 case 'missed_incoming_call':
102 return t('missed_incoming_call', { ...messageI18nContext });
103 case 'unknown_error_alert':
104 return t('unknown_error_alert');
105 case 'username_input_helper_text_empty':
106 return t('username_input_helper_text_empty');
107 case 'password_input_helper_text_empty':
108 return t('password_input_helper_text_empty');
109 case 'login_invalid_password':
110 return t('login_invalid_password');
111 case 'registration_success':
112 return t('registration_success');
113 default:
114 return t('unknown_error_alert');
115 }
116 },
117 [t]
118 );
119
120 const value = {
121 alertContent,
122 setAlertContent,
Ziwei Wang45baf532023-02-16 15:41:49 -0500123 closeAlert,
Ziwei Wang49765ec2023-02-13 16:35:32 -0500124 };
125
126 return (
127 <>
128 <AlertSnackbar severity={alertContent.severity} open={alertContent.alertOpen} onClose={closeAlert}>
129 {getAlertMessageText(alertContent.messageI18nKey, alertContent.messageI18nContext)}
130 </AlertSnackbar>
131 <AlertSnackbarContext.Provider value={value}>{children}</AlertSnackbarContext.Provider>
132 </>
133 );
134};
135
136export default AlertSnackbarProvider;