Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
thecybernanny-webapp
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
asranov0003
thecybernanny-webapp
Commits
7871a959
Commit
7871a959
authored
Jul 04, 2025
by
asranov0003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: render notification list
parent
7fd1cc7d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
205 additions
and
5 deletions
+205
-5
en.json
src/locales/en/en.json
+4
-0
ru.json
src/locales/ru/ru.json
+4
-0
Home.css
src/pages/Home/Home.css
+4
-0
Home.tsx
src/pages/Home/Home.tsx
+1
-1
Notifications.css
src/pages/Notifications/Notifications.css
+53
-0
Notifications.tsx
src/pages/Notifications/Notifications.tsx
+56
-2
Settings.css
src/pages/Settings/Settings.css
+4
-0
Settings.tsx
src/pages/Settings/Settings.tsx
+1
-1
Subscription.css
src/pages/Subscription/Subscription.css
+4
-0
Subscription.tsx
src/pages/Subscription/Subscription.tsx
+1
-1
notificationSlice.ts
src/stores/slices/notificationSlice.ts
+71
-0
store.ts
src/stores/store.ts
+2
-0
No files found.
src/locales/en/en.json
View file @
7871a959
...
...
@@ -33,6 +33,10 @@
"verified"
:
"Verified"
,
"unVerified"
:
"Unverified"
},
"notification"
:
{
"title"
:
"Notifications"
,
"empty"
:
"No notifications"
},
"pincode"
:
{
"enterTitle"
:
"Enter your PIN Code"
,
"createTitle"
:
"Create your PIN Code"
,
...
...
src/locales/ru/ru.json
View file @
7871a959
...
...
@@ -33,6 +33,10 @@
"verified"
:
"Подтверждено"
,
"unVerified"
:
"Не подтверждено"
},
"notification"
:
{
"title"
:
"Уведомления"
,
"empty"
:
"Нет уведомлений"
},
"pincode"
:
{
"enterTitle"
:
"Введите PIN-код"
,
"createTitle"
:
"Создайте PIN-код"
,
...
...
src/pages/Home/Home.css
View file @
7871a959
.home
{
padding
:
0
1rem
;
}
\ No newline at end of file
src/pages/Home/Home.tsx
View file @
7871a959
...
...
@@ -2,7 +2,7 @@ import React from "react";
import
"./Home.css"
;
const
Home
:
React
.
FC
=
()
=>
{
return
<
div
>
Home
</
div
>;
return
<
div
className=
"home"
>
Home
</
div
>;
};
export
default
Home
;
src/pages/Notifications/Notifications.css
View file @
7871a959
.notifications
{
padding
:
0
1rem
;
}
.notification__title
{
margin-bottom
:
1rem
;
}
.notifications__list
{
display
:
flex
;
flex-direction
:
column
;
gap
:
1rem
;
}
.notification
{
padding
:
1rem
;
background
:
#ffffff
;
border-radius
:
0.5rem
;
}
.notification__caption
{
font-weight
:
bold
;
display
:
flex
;
align-items
:
center
;
gap
:
0.5rem
;
}
.notification__caption__icon
{
font-size
:
1.5rem
;
color
:
var
(
--danger-color
);
}
.notification__text
{
font-size
:
0.875rem
;
margin
:
0.5rem
0
;
white-space
:
pre-wrap
;
word-break
:
break-word
;
overflow-wrap
:
anywhere
;
}
.notification__date
{
display
:
flex
;
justify-content
:
space-between
;
font-size
:
0.875rem
;
color
:
var
(
--gray-color
);
}
.notification__date__icon
{
font-size
:
1.2rem
;
color
:
var
(
--primary-color
);
}
\ No newline at end of file
src/pages/Notifications/Notifications.tsx
View file @
7871a959
import
React
from
"react"
;
import
React
,
{
useEffect
}
from
"react"
;
import
"./Notifications.css"
;
import
{
useAppDispatch
,
useAppSelector
,
type
RootState
,
}
from
"../../stores/store"
;
import
{
getList
}
from
"../../stores/slices/notificationSlice"
;
import
{
MdBlockFlipped
}
from
"react-icons/md"
;
import
{
IoPhonePortraitOutline
}
from
"react-icons/io5"
;
import
{
useTranslation
}
from
"react-i18next"
;
const
Notifications
:
React
.
FC
=
()
=>
{
return
<
div
>
Notifications
</
div
>;
const
{
t
}
=
useTranslation
();
const
dispatch
=
useAppDispatch
();
const
getDefaultDates
=
()
=>
{
const
dateTo
=
new
Date
();
const
dateFrom
=
new
Date
(
dateTo
);
dateFrom
.
setDate
(
dateTo
.
getDate
()
-
30
);
return
{
dateFrom
,
dateTo
};
};
const
{
notifications
}
=
useAppSelector
(
(
state
:
RootState
)
=>
state
.
notification
);
useEffect
(()
=>
{
dispatch
(
getList
(
getDefaultDates
()));
},
[
dispatch
]);
return
(
<
div
className=
"notifications"
>
<
h3
className=
"notification__title"
>
{
t
(
"notification.title"
)
}
</
h3
>
<
div
className=
"notifications__list"
>
{
notifications
.
length
>
0
?
(
notifications
.
map
((
notification
)
=>
(
<
div
className=
"notification"
key=
{
notification
.
id
}
>
<
div
className=
"notification__caption"
>
<
MdBlockFlipped
className=
"notification__caption__icon"
/>
<
p
>
{
notification
.
caption
}
</
p
>
</
div
>
<
p
className=
"notification__text"
>
{
notification
.
text
}
</
p
>
<
div
className=
"notification__date"
>
<
IoPhonePortraitOutline
className=
"notification__date__icon"
/>
{
new
Date
(
notification
.
date
).
toLocaleString
()
}
</
div
>
</
div
>
))
)
:
(
<
p
>
{
t
(
"notification.empty"
)
}
</
p
>
)
}
</
div
>
</
div
>
);
};
export
default
Notifications
;
src/pages/Settings/Settings.css
View file @
7871a959
.settings
{
padding
:
0
1rem
;
}
\ No newline at end of file
src/pages/Settings/Settings.tsx
View file @
7871a959
...
...
@@ -2,7 +2,7 @@ import React from "react";
import
"./Settings.css"
;
const
Settings
:
React
.
FC
=
()
=>
{
return
<
div
>
Settings
</
div
>;
return
<
div
className=
"settings"
>
Settings
</
div
>;
};
export
default
Settings
;
src/pages/Subscription/Subscription.css
View file @
7871a959
.subscription
{
padding
:
0
1rem
;
}
\ No newline at end of file
src/pages/Subscription/Subscription.tsx
View file @
7871a959
...
...
@@ -2,7 +2,7 @@ import React from "react";
import
"./Subscription.css"
;
const
Subscription
:
React
.
FC
=
()
=>
{
return
<
div
>
Subscription
</
div
>;
return
<
div
className=
"subscription"
>
Subscription
</
div
>;
};
export
default
Subscription
;
src/stores/slices/notificationSlice.ts
0 → 100644
View file @
7871a959
import
{
createAsyncThunk
,
createSlice
}
from
"@reduxjs/toolkit"
;
import
{
sendRpcRequest
}
from
"../../services/apiClient"
;
interface
INotification
{
id
:
string
;
caption
:
string
;
text
:
string
;
action
:
string
;
date
:
string
;
deviceId
:
string
;
type
:
string
;
}
interface
INotificationState
{
notifications
:
INotification
[];
loading
:
boolean
;
}
const
initialState
:
INotificationState
=
{
notifications
:
[],
loading
:
false
,
};
export
const
getList
=
createAsyncThunk
(
"notifications/fetch"
,
async
(
{
dateFrom
,
dateTo
}:
{
dateFrom
:
Date
;
dateTo
:
Date
},
{
rejectWithValue
}
)
=>
{
try
{
const
response
=
await
sendRpcRequest
<
{
list
:
INotification
[]
}
>
(
"notif.getList"
,
{
dateFrom
,
dateTo
,
recStart
:
0
,
recLimit
:
30
,
}
);
return
response
.
list
;
}
catch
(
error
:
unknown
)
{
if
(
typeof
error
===
"object"
&&
error
!==
null
&&
"message"
in
error
)
{
return
rejectWithValue
(
error
.
message
);
}
return
rejectWithValue
(
"Unknown error occurred"
);
}
}
);
const
notificationSlice
=
createSlice
({
name
:
"notifications"
,
initialState
,
reducers
:
{},
extraReducers
:
(
builder
)
=>
{
builder
.
addCase
(
getList
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
})
.
addCase
(
getList
.
fulfilled
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
notifications
=
action
.
payload
;
})
.
addCase
(
getList
.
rejected
,
(
state
)
=>
{
state
.
loading
=
false
;
});
},
});
export
default
notificationSlice
.
reducer
;
src/stores/store.ts
View file @
7871a959
import
{
configureStore
}
from
"@reduxjs/toolkit"
;
import
authSlice
from
"./slices/authSlice"
;
import
accountSlice
from
"./slices/accountSlice"
;
import
notificationSlice
from
"./slices/notificationSlice"
;
import
{
useDispatch
,
useSelector
,
...
...
@@ -11,6 +12,7 @@ export const store = configureStore({
reducer
:
{
auth
:
authSlice
,
account
:
accountSlice
,
notification
:
notificationSlice
,
},
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment