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
c8cdb45d
Commit
c8cdb45d
authored
Jul 30, 2025
by
asranov0003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add info modal
parent
0b3b7371
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
126 additions
and
13 deletions
+126
-13
Header.tsx
src/layouts/Header/Header.tsx
+91
-9
en.json
src/locales/en/en.json
+17
-2
ru.json
src/locales/ru/ru.json
+18
-2
No files found.
src/layouts/Header/Header.tsx
View file @
c8cdb45d
...
@@ -26,9 +26,12 @@ import {
...
@@ -26,9 +26,12 @@ import {
import
CDeviceSelect
from
"../../components/CDeviceSelect"
;
import
CDeviceSelect
from
"../../components/CDeviceSelect"
;
import
{
logout
}
from
"../../stores/slices/authSlice"
;
import
{
logout
}
from
"../../stores/slices/authSlice"
;
import
TheCybernanny
from
"../../assets/images/TheCybernanny.png"
;
import
TheCybernanny
from
"../../assets/images/TheCybernanny.png"
;
import
CButton
from
"../../components/CButton"
;
import
CModal
from
"../../components/CModal"
;
const
Header
:
React
.
FC
=
()
=>
{
const
Header
:
React
.
FC
=
()
=>
{
const
[
isSidebarOpen
,
setIsSidebarOpen
]
=
useState
(
false
);
const
[
isSidebarOpen
,
setIsSidebarOpen
]
=
useState
(
false
);
const
[
isOpenInfoModal
,
setIsOpenInfoModal
]
=
useState
(
false
);
const
sidebarRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
sidebarRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
const
dispatch
=
useAppDispatch
();
const
dispatch
=
useAppDispatch
();
...
@@ -53,6 +56,20 @@ const Header: React.FC = () => {
...
@@ -53,6 +56,20 @@ const Header: React.FC = () => {
}
}
};
};
const
toggleInfoModal
=
()
=>
{
setIsOpenInfoModal
((
prev
)
=>
!
prev
);
};
const
share
=
()
=>
{
const
message
=
"https://t.me/CyberNannyAppBot"
;
if
(
window
.
Telegram
?.
WebApp
?.
openTelegramLink
)
{
window
.
Telegram
.
WebApp
.
openTelegramLink
(
`https://t.me/share/url?url=
${
encodeURIComponent
(
message
)}
`
);
}
};
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
isSidebarOpen
)
{
if
(
isSidebarOpen
)
{
document
.
addEventListener
(
"mousedown"
,
handleOutsideClick
);
document
.
addEventListener
(
"mousedown"
,
handleOutsideClick
);
...
@@ -87,15 +104,23 @@ const Header: React.FC = () => {
...
@@ -87,15 +104,23 @@ const Header: React.FC = () => {
</
div
>
</
div
>
<
div
className=
"header__devices"
>
<
div
className=
"header__devices"
>
<
CDeviceSelect
{
devices
.
length
>
0
?
(
devices=
{
devices
}
<
CDeviceSelect
selectedDevice=
{
selectedDevice
}
devices=
{
devices
}
onDeviceChange=
{
(
name
)
=>
dispatch
(
setSelectedDevice
(
name
))
}
selectedDevice=
{
selectedDevice
}
disabled=
{
!
devices
.
length
}
onDeviceChange=
{
(
name
)
=>
dispatch
(
setSelectedDevice
(
name
))
}
style=
{
{
width
:
"220px"
}
}
disabled=
{
!
devices
.
length
}
className=
"header__device-select"
style=
{
{
width
:
"220px"
}
}
placeholder=
{
t
(
"common.selectDevice"
)
}
className=
"header__device-select"
/>
placeholder=
{
t
(
"common.selectDevice"
)
}
/>
)
:
(
<
CButton
title=
{
t
(
"help.howToStart"
)
}
onClick=
{
toggleInfoModal
}
variant=
"primary"
/>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -181,6 +206,63 @@ const Header: React.FC = () => {
...
@@ -181,6 +206,63 @@ const Header: React.FC = () => {
</
div
>
</
div
>
</
div
>
</
div
>
)
}
)
}
<
CModal
isOpen=
{
isOpenInfoModal
}
onToggle=
{
toggleInfoModal
}
content=
{
<
div
className=
"modal__box"
>
<
h3
className=
"modal__box__title"
>
{
t
(
"help.howToStart"
)
}
</
h3
>
<
div
>
<
h4
>
{
t
(
"help.parentPhone"
)
}
</
h4
>
<
p
>
{
t
(
"help.parentPhoneDesc1"
)
}
</
p
>
<
p
>
{
t
(
"help.parentPhoneDesc2"
)
}
</
p
>
<
p
>
{
t
(
"help.parentPhoneDesc3"
)
}
</
p
>
</
div
>
<
div
>
<
h4
>
{
t
(
"help.childPhone"
)
}
</
h4
>
<
p
>
{
t
(
"help.childPhoneDesc1"
)
}
</
p
>
<
p
>
{
t
(
"help.childPhoneDesc2"
)
}
</
p
>
<
p
>
{
t
(
"help.childPhoneDesc3"
)
}
</
p
>
</
div
>
<
br
/>
<
p
>
{
t
(
"help.howToStartDesc"
)
}
</
p
>
<
a
href=
"https://apps.apple.com/uz/app/%D0%BA%D0%B8%D0%B1%D0%B5%D1%80%D0%BD%D1%8F%D0%BD%D1%8F/id6740760058"
target=
"_blank"
rel=
"noopener noreferrer"
>
{
t
(
"common.downloadForIos"
)
}
</
a
>
<
a
href=
"https://play.google.com/store/apps/details?id=com.thecybernanny.adroapp"
target=
"_blank"
rel=
"noopener noreferrer"
>
{
t
(
"common.downloadForAndroid"
)
}
</
a
>
<
div
className=
"modal__box__actions"
>
<
CButton
title=
{
t
(
"button.share"
)
}
variant=
"primary"
onClick=
{
share
}
/>
<
CButton
title=
{
t
(
"button.ok"
)
}
onClick=
{
toggleInfoModal
}
variant=
"primary"
/>
</
div
>
</
div
>
}
/>
</>
</>
);
);
};
};
...
...
src/locales/en/en.json
View file @
c8cdb45d
...
@@ -14,7 +14,9 @@
...
@@ -14,7 +14,9 @@
"password"
:
"Password"
,
"password"
:
"Password"
,
"passwordPlaceholder"
:
"Enter your password"
,
"passwordPlaceholder"
:
"Enter your password"
,
"selectDevice"
:
"Select Device"
,
"selectDevice"
:
"Select Device"
,
"noData"
:
"No data found"
"noData"
:
"No data found"
,
"downloadForAndroid"
:
"Download for Android"
,
"downloadForIos"
:
"Download for iOS"
},
},
"auth"
:
{
"auth"
:
{
"entrance"
:
"Sign In"
,
"entrance"
:
"Sign In"
,
...
@@ -160,6 +162,18 @@
...
@@ -160,6 +162,18 @@
"title"
:
"Logout"
,
"title"
:
"Logout"
,
"desc"
:
"Are you sure you want to continue?"
"desc"
:
"Are you sure you want to continue?"
},
},
"help"
:
{
"howToStart"
:
"Как начать?"
,
"howToStartDesc"
:
"* Вы можете использовать один аккаунт на нескольких устройствах"
,
"parentPhone"
:
"Телефон родителя"
,
"parentPhoneDesc1"
:
"• Скачайте и установите приложение на телефон родителя"
,
"parentPhoneDesc2"
:
"• Создайте один аккаунт на всю семью"
,
"parentPhoneDesc3"
:
"• Выберите режим Родитель"
,
"childPhone"
:
"Телефон ребенка"
,
"childPhoneDesc1"
:
"• Скачайте и установите приложение на телефон ребенка"
,
"childPhoneDesc2"
:
"• Войдите под Вашим аккаунтом"
,
"childPhoneDesc3"
:
"• Выберите режим Ребенок"
},
"button"
:
{
"button"
:
{
"login"
:
"Login"
,
"login"
:
"Login"
,
"register"
:
"Register"
,
"register"
:
"Register"
,
...
@@ -171,7 +185,8 @@
...
@@ -171,7 +185,8 @@
"delete"
:
"Delete"
,
"delete"
:
"Delete"
,
"search"
:
"Search"
,
"search"
:
"Search"
,
"save"
:
"Save"
,
"save"
:
"Save"
,
"confirm"
:
"Confirm"
"confirm"
:
"Confirm"
,
"share"
:
"Share"
},
},
"notFound"
:
{
"notFound"
:
{
"code"
:
"404"
,
"code"
:
"404"
,
...
...
src/locales/ru/ru.json
View file @
c8cdb45d
...
@@ -14,7 +14,9 @@
...
@@ -14,7 +14,9 @@
"password"
:
"Пароль"
,
"password"
:
"Пароль"
,
"passwordPlaceholder"
:
"Введите ваш пароль"
,
"passwordPlaceholder"
:
"Введите ваш пароль"
,
"selectDevice"
:
"Выбрать устройство"
,
"selectDevice"
:
"Выбрать устройство"
,
"noData"
:
"Данные не найдены"
"noData"
:
"Данные не найдены"
,
"downloadForAndroid"
:
"Скачать для Android"
,
"downloadForIos"
:
"Скачать для iOS"
},
},
"auth"
:
{
"auth"
:
{
"entrance"
:
"Вход"
,
"entrance"
:
"Вход"
,
...
@@ -160,6 +162,18 @@
...
@@ -160,6 +162,18 @@
"title"
:
"Выйти"
,
"title"
:
"Выйти"
,
"desc"
:
"Вы уверены, что хотите продолжить?"
"desc"
:
"Вы уверены, что хотите продолжить?"
},
},
"help"
:
{
"howToStart"
:
"Как начать?"
,
"howToStartDesc"
:
"* Вы можете использовать один аккаунт на нескольких устройствах"
,
"parentPhone"
:
"Телефон родителя"
,
"parentPhoneDesc1"
:
"• Скачайте и установите приложение на телефон родителя"
,
"parentPhoneDesc2"
:
"• Создайте один аккаунт на всю семью"
,
"parentPhoneDesc3"
:
"• Выберите режим Родитель"
,
"childPhone"
:
"Телефон ребенка"
,
"childPhoneDesc1"
:
"• Скачайте и установите приложение на телефон ребенка"
,
"childPhoneDesc2"
:
"• Войдите под Вашим аккаунтом"
,
"childPhoneDesc3"
:
"• Выберите режим Ребенок"
},
"button"
:
{
"button"
:
{
"login"
:
"Войти"
,
"login"
:
"Войти"
,
"register"
:
"Зарегистрироваться"
,
"register"
:
"Зарегистрироваться"
,
...
@@ -171,7 +185,9 @@
...
@@ -171,7 +185,9 @@
"delete"
:
"Удалить"
,
"delete"
:
"Удалить"
,
"search"
:
"Поиск"
,
"search"
:
"Поиск"
,
"save"
:
"Сохранить"
,
"save"
:
"Сохранить"
,
"confirm"
:
"Подтвердить"
"confirm"
:
"Подтвердить"
,
"ok"
:
"Ок"
,
"share"
:
"Поделиться"
},
},
"notFound"
:
{
"notFound"
:
{
"code"
:
"404"
,
"code"
:
"404"
,
...
...
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