Skip to content

Commit

Permalink
feat(notifier): add notifier service
Browse files Browse the repository at this point in the history
  • Loading branch information
Ibrahimsyah committed Mar 31, 2024
1 parent 47f469b commit c0e6865
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 31 deletions.
47 changes: 42 additions & 5 deletions src/pages/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,53 @@
import { Box, LinearProgress, Typography } from '@mui/joy';
import { Box, Button, LinearProgress, Snackbar, Typography } from '@mui/joy';
import './App.css';

import { Outlet, RouterProvider, createRootRoute, createRoute, createRouter, redirect } from '@tanstack/react-router';
import useAuthStore from '@/stores/auth';
import useNotification from '@/stores/notification';
import { useQueryClient } from '@tanstack/react-query';

// Root route section
const rootRoute = createRootRoute({
component: () => (
const Root = () => {
const notification = useNotification()
const queryClient = useQueryClient()

queryClient.setDefaultOptions({
mutations: {
onError: (error) => {
console.log(error)
notification.fire(error.message, 'danger')
}
}
})

return (
<Box sx={{ minHeight: '100vh' }}>
<Snackbar
variant='soft'
autoHideDuration={3000}
color={notification.type}
open={notification.is_open}
onClose={notification.clear}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
endDecorator={
<Button
onClick={() => notification.clear()}
size="sm"
variant="soft"
color={notification.type}
>
Tutup
</Button>
}
>{notification.message}</Snackbar>

<Outlet />
</Box>
),
)
}

// Root route section
const rootRoute = createRootRoute({
component: Root,
notFoundComponent: () => <Typography>Halaman Tidak Ditemukan, Hubungi Admin</Typography>
})

Expand Down
6 changes: 4 additions & 2 deletions src/pages/auth/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import authAPI from '@/apis/auth'
import { useMutation, useQuery } from "@tanstack/react-query"
import { AuthRequest } from "@/apis/auth.types"
import useAuthStore from "@/stores/auth"
import useNotification from "@/stores/notification"

const Auth = () => {
const [isLoginState, setIsLoginState] = useState(true)
Expand All @@ -21,6 +22,7 @@ const Auth = () => {
})
const auth = useAuthStore()
const navigate = useNavigate()
const notification = useNotification()

const authMutation = useMutation({
mutationFn: (request: AuthRequest) => isLoginState ? authAPI.loginUser(request) : authAPI.registerUser(request),
Expand Down Expand Up @@ -66,16 +68,16 @@ const Auth = () => {
return email !== "" && password !== "";
}

console.log(userInfoQuery.data)
useEffect(() => {
if (userInfoQuery.isLoading) return
if (userInfoQuery.data?.is_active) {
navigate({
to: '/dashboard',
replace: true,
})
notification.fire(`Selamat Datang ${userInfoQuery.data.name}!`)
}
}, [userInfoQuery.data?.is_active, userInfoQuery.isLoading, navigate])
}, [userInfoQuery.data, userInfoQuery.isLoading, navigate, notification])

return (
<Grid container flexDirection='column' gap={2} sx={{ p: 2, height: '100vh' }} alignItems='center' justifyContent='center' className="fade">
Expand Down
4 changes: 1 addition & 3 deletions src/pages/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ const tabs = [

const App = () => {
return (
// <Box display='flex' flexDirection='column' sx={{ height: '100vh' }}>
<Grid flexDirection='column' display='flex' sx={{ minHeight: '100vh', background: 'white' }}>
<Outlet />
<BottomNavigation />
</Grid>
// </Box>
)
}

Expand All @@ -59,7 +57,7 @@ const BottomNavigation = () => {
left: 0,
right: 0,
boxShadow: theme.shadow.sm,
// '--joy-shadowChannel': theme.vars.palette[colors[currentIndex]].darkChannel,
'--joy-shadowChannel': theme.vars.palette[colors[currentIndex]].darkChannel,
[`& .${tabClasses.root}`]: {
py: 1,
flex: 1,
Expand Down
5 changes: 5 additions & 0 deletions src/pages/home/schedule/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import ConfirmationDialog from "../../../components/confirmation-dialog"
import settingAPI from "@/apis/setting"
import useTabStore from "@/stores/tab";
import { createLazyRoute } from "@tanstack/react-router";
import useNotification from "@/stores/notification";

const scheduleModeTabMap: { [key: number]: SchedulerRecurringMode } = {
0: SchedulerRecurringMode.NONE,
Expand Down Expand Up @@ -55,6 +56,7 @@ const Schedule = () => {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [schedulerAPI.QUERY_KEY_GET_UPCOMING_SCHEDULES, 1] })
setIsAddModalOpen(false)
notification.fire("Berhasil menambah jadwal")
},
})

Expand All @@ -63,6 +65,7 @@ const Schedule = () => {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [schedulerAPI.QUERY_KEY_GET_UPCOMING_SCHEDULES, 1] })
setIsDeleteConfirmationOpen(false)
notification.fire("Berhasil menghapus jadwal")
},
})

Expand All @@ -74,6 +77,7 @@ const Schedule = () => {
setExpandedSchedule({
id: -1,
})
notification.fire("Berhasil mengubah jadwal")
},
})

Expand All @@ -89,6 +93,7 @@ const Schedule = () => {
id: -1,
})
const setTab = useTabStore(store => store.setTab)
const notification = useNotification()

const upcomingSchedules = useMemo(() => upcomingSchedulesQuery.data, [upcomingSchedulesQuery.data])
const actuators = useMemo(() => [...actuatorsQuery.data || []], [actuatorsQuery.data])
Expand Down
6 changes: 5 additions & 1 deletion src/pages/home/setting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import { Actuator } from "@/apis/setting.types"
import { createLazyRoute, useNavigate } from "@tanstack/react-router"
import ConfirmationDialog from "@/components/confirmation-dialog"
import useAuthStore from "@/stores/auth"
import useNotification from "@/stores/notification"

const Setting = () => {
const [selectedPanel, setSelectedPanel] = useState<Actuator | null>()
const [isLogoutModalOpened, setLogoutModalOpened] = useState(false)
const auth = useAuthStore()
const navigate = useNavigate()
const notification = useNotification()

const queryClient = useQueryClient()
const actuators = useQuery({
Expand All @@ -27,6 +29,7 @@ const Setting = () => {
onSuccess: () => {
setSelectedPanel(null)
queryClient.invalidateQueries({ queryKey: [settingAPI.QUERY_KEY_GET_ACTUATORS, 1] })
notification.fire("Berhasil mengubah panel")
}
})

Expand All @@ -40,10 +43,11 @@ const Setting = () => {
queryClient.removeQueries({queryKey: [authAPI.QUERY_KEY_GET_USER_INFO]})
setLogoutModalOpened(false)
navigate({ to: '/auth', replace: true })
notification.fire('Berhasil Keluar Akun')
}

return <>
<Box sx={{ px: 2 }}>
<Box sx={{ px: 2 }} className="fade">
<Typography sx={{ mt: 4 }} level="h2" fontWeight='500'>Pengaturan</Typography>
<Grid container sx={{ pt: 3 }} flexDirection='column' gap={2}>
{actuators.isLoading && <LinearProgress />}
Expand Down
18 changes: 18 additions & 0 deletions src/stores/notification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { create } from "zustand"
import { NotificationStore, NotificationType } from "./notification.types"

const useNotification = create<NotificationStore>()(
(set) => ({
message: "",
type: "success",
fire: (message: string, type: NotificationType = 'success') => {
set(() => ({ message, type, is_open: true }))
},
is_open: false,
clear: () => {
set(() => ({ message: "", is_open: false }))
}
})
)

export default useNotification
9 changes: 9 additions & 0 deletions src/stores/notification.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type NotificationType = 'success' | 'danger'

export type NotificationStore = {
message: string
type: NotificationType,
is_open: boolean,
fire: (message: string, type?: NotificationType) => void,
clear: () => void
}
8 changes: 5 additions & 3 deletions src/utils/network.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import useAuthStore from "@/stores/auth"
import string from "./string"

const BASE_URL = import.meta.env.VITE_BASE_URL

Expand All @@ -23,11 +22,14 @@ const doRequest = async <T>(endpoint: string, config: any): Promise<T> => {
const response = await fetch(buildURL(endpoint), buildRequestConfig(config))
const json = await response.json()
if (!json.is_success || response.status < 200 || response.status > 299) {
return Promise.reject(string.toTitleCase(json.error))
return Promise.reject({
message: json.error,
code: json.code
})
}
return Promise.resolve(json.data)
} catch (err: any) {
return Promise.reject(err.message.replace(/\b\w/g, (s: string) => s.toUpperCase()))
return Promise.reject(err)
}
}

Expand Down
17 changes: 0 additions & 17 deletions src/utils/string.ts

This file was deleted.

0 comments on commit c0e6865

Please sign in to comment.