diff --git a/src/App.tsx b/src/App.tsx index 0561a2d..15dd700 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,14 @@ -import CompanyInfoModal from './components/CompanyInfoModal/CompanyInfoModal' -import './App.css' +// import CompanyInfoModal from "./components/CompanyInfoModal/CompanyInfoModal"; +import NotificationModal from "./components/NotificationModal/NotificationModal"; +import "./App.css"; function App() { - return ( -
- +
+ {/* */} + {/* */}
- ) + ); } -export default App +export default App; diff --git a/src/components/CompanyInfoItem/CompanyInfoItem.tsx b/src/components/CompanyInfoItem/CompanyInfoItem.tsx index ce41cea..6aaff0c 100644 --- a/src/components/CompanyInfoItem/CompanyInfoItem.tsx +++ b/src/components/CompanyInfoItem/CompanyInfoItem.tsx @@ -12,8 +12,8 @@ const CompanyInfoItem = ({ companyInfoItem }: CompanyInfoItemProps) => { return (
-
{label}
-
{title}
+
{label}
+
{title}
diff --git a/src/components/CompanyInfoModal/CompanyInfoModal.tsx b/src/components/CompanyInfoModal/CompanyInfoModal.tsx index d3e11ac..7f17545 100644 --- a/src/components/CompanyInfoModal/CompanyInfoModal.tsx +++ b/src/components/CompanyInfoModal/CompanyInfoModal.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; import IconWrapper from "../../icons/IconWrapper/IconWrapper"; import CrossIcon from "../../icons/CrossIcon/CrossIcon"; -import CompanyInfoItem from "../CompanyInfoItem/CompanyInfoItem"; import EmployeesList from "../EmployeesList/EmployeesList"; import ICompanyEmployee from "../../types/companyEmployee"; import ICompanyInfoItem from "../../types/companyInfoItem"; @@ -12,27 +11,41 @@ import IProjectItem from "../../types/projectItem"; const companyEmployeeItems: ICompanyEmployee[] = [ { name: "Анастасия Кошкина", - status: "В сети", + status: "online", image: "Employee.png", id: "1", }, { name: "Анастасия Кошкина", - status: "Не в сети", + status: "offline", image: "Employee.png", id: "2", }, { name: "Анастасия Кошкина", - status: "На демонстрации", + status: "at demonstration", image: "Employee.png", id: "3", }, ]; const projectItems: IProjectItem[] = [ - { title: "ЖК «Акватория»", image: "building1.png", id: "1" }, - { title: "ЖК «Новатор»", image: "building2.png", id: "2" }, + { + title: "ЖК «Акватория»", + image: "building1.png", + id: "1", + subscriptionSessionCount: 3, + subscriptionUntil: "2023-11-07T07:54:58.392+00:00", + applicationVersion: "1.23", + }, + { + title: "ЖК «Новатор»", + image: "building2.png", + id: "2", + subscriptionSessionCount: 3, + subscriptionUntil: "2023-11-07T07:54:58.392+00:00", + applicationVersion: "1.23", + }, ]; const companyInfoItems: ICompanyInfoItem[] = [ @@ -45,6 +58,12 @@ const companyInfoItems: ICompanyInfoItem[] = [ const CompanyInfo = () => { const [tab, setTab] = useState<"Сотрудники" | "Проекты">("Сотрудники"); + const handleOnTabClick = (currentTab: "Сотрудники" | "Проекты") => { + return () => { + setTab(currentTab); + }; + }; + return (
@@ -58,24 +77,30 @@ const CompanyInfo = () => {
-
-
+
-
- - {/* */} + {tab === "Сотрудники" && ( + + )} + {tab === "Проекты" && }
diff --git a/src/components/EmployeeItem/EmployeeItem.tsx b/src/components/EmployeeItem/EmployeeItem.tsx index 0ed1a77..181c5b7 100644 --- a/src/components/EmployeeItem/EmployeeItem.tsx +++ b/src/components/EmployeeItem/EmployeeItem.tsx @@ -6,13 +6,22 @@ interface EmployeeItemProps { const EmployeeItem = ({ employee }: EmployeeItemProps) => { const { image, id, name, status } = employee; + const statusColor = { + online: { color: "#49A1F5", label: "В сети" }, + offline: { color: "#27AE60", label: "Не в сети" }, + "at demonstration": { color: "#EB5757", label: "На демонстрации" }, + }; return (
{name}
{name}
-
{status}
+
+ • {statusColor[status].label} +
); diff --git a/src/components/NotificationItem/NotificationItem.tsx b/src/components/NotificationItem/NotificationItem.tsx new file mode 100644 index 0000000..5eabbea --- /dev/null +++ b/src/components/NotificationItem/NotificationItem.tsx @@ -0,0 +1,92 @@ +import INotification from "../../types/notification"; +import IconWrapper from "../../icons/IconWrapper/IconWrapper"; +import IsNotificationReadIcon from "../../icons/IsNotificationReadIcon/IsNotificationReadIcon"; +import { format, parseISO } from "date-fns"; +import { useState } from "react"; +import SystemNotificationIcon from "../../icons/SystemNotificationIcon/SystemNotificationIcon"; + +interface NotificationItemProps { + notification: INotification; +} + +const NotificationItem = ({ notification }: NotificationItemProps) => { + const date = format(parseISO(notification.date), "dd.mm.yyyy"); + const [selectedNotificationIds, setSelectedNotificationIds] = useState< + string[] + >([]); + + const handleOnNotificationClick = (notificationId: string) => { + return () => { + if (selectedNotificationIds.includes(notificationId)) { + const updatedSelectedNotificatios = selectedNotificationIds.filter( + (notification) => notification !== notificationId + ); + setSelectedNotificationIds(updatedSelectedNotificatios); + } else { + const updatedSelectedNotificatios = [ + ...selectedNotificationIds, + notificationId, + ]; + setSelectedNotificationIds(updatedSelectedNotificatios); + } + }; + }; + + return ( +
+ {notification.type === "Employee" ? ( + {notification.title} + ) : ( + + + + )} +
+
+
+

{notification.title}

+
+ {!notification.isRead && + !selectedNotificationIds.includes(notification.id) && ( + + + + )} +
+
+
+ {notification.content} +
+
+
{date}
+ {notification.type === "Employee" ? ( + + ) : ( + + )} +
+
+
+
+ ); +}; + +export default NotificationItem; diff --git a/src/components/NotificationList/NotificationList.tsx b/src/components/NotificationList/NotificationList.tsx new file mode 100644 index 0000000..13d2520 --- /dev/null +++ b/src/components/NotificationList/NotificationList.tsx @@ -0,0 +1,20 @@ +import INotification from "../../types/notification"; +import NotificationItem from "../NotificationItem/NotificationItem"; + +interface NotificationListProps { + notifications: INotification[]; +} + +const NotificationList = ({ notifications }: NotificationListProps) => { + return ( +
+ {notifications.map((notification) => { + return ( + + ); + })} +
+ ); +}; + +export default NotificationList; diff --git a/src/components/NotificationModal/NotificationModal.tsx b/src/components/NotificationModal/NotificationModal.tsx new file mode 100644 index 0000000..37f6bb4 --- /dev/null +++ b/src/components/NotificationModal/NotificationModal.tsx @@ -0,0 +1,72 @@ +import { useState } from "react"; +import CrossIcon from "../../icons/CrossIcon/CrossIcon"; +import IconWrapper from "../../icons/IconWrapper/IconWrapper"; +import INotification from "../../types/notification"; +import NotificationList from "../NotificationList/NotificationList"; + +const notificationData: INotification[] = [ + { + type: "Employee", + isRead: false, + date: "2023-11-07T07:54:58.392+00:00", + image: "Employee.png", + id: "1", + title: "Анастасия Кошкина", + content: + "Взяла дополнительные демонстрации вместо Елизаветы, планирую закрыть", + }, + { + type: "Employee", + isRead: true, + date: "2023-11-07T07:54:58.392+00:00", + image: "Employee.png", + id: "2", + title: "Анастасия Кошкина", + content: + "Взяла дополнительные демонстрации вместо Елизаветы, планирую закрыть их и еще несколько, также хотелось бы сообщить о чем-то, но я не знаю о чем, я просто текст набираю", + }, + { + type: "System", + isRead: false, + date: "2023-11-07T07:54:58.392+00:00", + image: undefined, + id: "3", + title: "Тип системного уведомления", + content: "Сообщение", + }, +]; + +const NotificationModal = () => { + const [notifications, setNotifications] = useState(notificationData); + + const handleMarkAsRead = () => { + const updatedNotification = notifications.map((notification) => { + return { ...notification, isRead: true }; + }); + + setNotifications(updatedNotification); + }; + return ( +
+
+
Уведомления
+ + + +
+
+ +
+
+ +
+
+ ); +}; + +export default NotificationModal; diff --git a/src/components/ProjectList/ProjectList.tsx b/src/components/ProjectList/ProjectList.tsx index b1480d7..424d1b7 100644 --- a/src/components/ProjectList/ProjectList.tsx +++ b/src/components/ProjectList/ProjectList.tsx @@ -1,18 +1,88 @@ +import { useState } from "react"; import IProjectItem from "../../types/projectItem"; +import { format, parseISO } from "date-fns"; interface ProjectProps { projectItems: IProjectItem[]; } const ProjectList = ({ projectItems }: ProjectProps) => { + const [selectedProjectIds, setSelectedProjectIds] = useState([ + projectItems[1].id, + ]); + + const handleOnProjectClick = (id: string) => { + return () => { + if (selectedProjectIds.includes(id)) { + const updatedProjectIds = [...selectedProjectIds].filter( + (projectId) => projectId !== id + ); + setSelectedProjectIds(updatedProjectIds); + } else { + const updatedProjectIds = [...selectedProjectIds, id]; + setSelectedProjectIds(updatedProjectIds); + } + }; + }; + return ( -
- {projectItems.map((item) => ( -
- {item.title} -
{item.title}
-
- ))} +
+ {projectItems.map((item) => { + const date = format(parseISO(item.subscriptionUntil), "dd.MM.yyyy"); + + return ( + <> +
+
+ {item.title} +
{item.title}
+
+ {selectedProjectIds.includes(item.id) ? ( +
+
+
+ Подписка +
+
+
Действует до:
+
{date}
+
+
+
Сессий одновременно:
{" "} +
+ {item.subscriptionSessionCount} +
+
+
+ +
+
+ Приложение +
+
+
Версия:
+
+ {item.applicationVersion} +
+
+
+ +
+ ) : ( + <> + )} +
+ + ); + })}
); }; diff --git a/src/icons/IconWrapper/IconWrapper.tsx b/src/icons/IconWrapper/IconWrapper.tsx index c9557ac..10d9edc 100644 --- a/src/icons/IconWrapper/IconWrapper.tsx +++ b/src/icons/IconWrapper/IconWrapper.tsx @@ -1,15 +1,10 @@ interface IconProps { - children: React.ReactElement, - className?: string + children: React.ReactElement; + className?: string; } -const IconWrapper = ({ children, className } : IconProps) => { +const IconWrapper = ({ children, className }: IconProps) => { + return
{children}
; +}; - return ( -
- {children} -
-) -} - -export default IconWrapper; \ No newline at end of file +export default IconWrapper; diff --git a/src/icons/IsNotificationReadIcon/IsNotificationReadIcon.tsx b/src/icons/IsNotificationReadIcon/IsNotificationReadIcon.tsx new file mode 100644 index 0000000..eabf51f --- /dev/null +++ b/src/icons/IsNotificationReadIcon/IsNotificationReadIcon.tsx @@ -0,0 +1,15 @@ +const IsNotificationReadIcon = () => { + return ( + + + + ); +}; + +export default IsNotificationReadIcon; diff --git a/src/icons/SystemNotificationIcon/SystemNotificationIcon.tsx b/src/icons/SystemNotificationIcon/SystemNotificationIcon.tsx new file mode 100644 index 0000000..d4710b0 --- /dev/null +++ b/src/icons/SystemNotificationIcon/SystemNotificationIcon.tsx @@ -0,0 +1,28 @@ +const SystemNotificationIcon = () => { + return ( + + + + + + ); +}; + +export default SystemNotificationIcon; diff --git a/src/index.css b/src/index.css index c673619..e14d34e 100644 --- a/src/index.css +++ b/src/index.css @@ -5,3 +5,19 @@ body { @apply bg-[#ccc]; } + +/* Scrollbar */ + +*::-webkit-scrollbar { + width: 8px; +} + +*::-webkit-scrollbar-thumb { + background-color: #858585; + border: 3.5px solid #fff; + border-radius: 4px; +} + +*::-webkit-scrollbar-thumb:hover { + border-width: 2px; +} diff --git a/src/types/companyEmployee.ts b/src/types/companyEmployee.ts index 36226cc..3ae1648 100644 --- a/src/types/companyEmployee.ts +++ b/src/types/companyEmployee.ts @@ -1,6 +1,6 @@ interface ICompanyEmployee { image: string; - status: "В сети" | "Не в сети" | "На демонстрации"; + status: "online" | "offline" | "at demonstration"; name: string; id: string; } diff --git a/src/types/notification.ts b/src/types/notification.ts new file mode 100644 index 0000000..027077c --- /dev/null +++ b/src/types/notification.ts @@ -0,0 +1,11 @@ +interface INotification { + title: string, + type: 'Employee' | 'System', + isRead: boolean, + date: string, + image: string | undefined, + id: string, + content: string, +} + +export default INotification; \ No newline at end of file diff --git a/src/types/projectItem.ts b/src/types/projectItem.ts index d0cb666..de3b83d 100644 --- a/src/types/projectItem.ts +++ b/src/types/projectItem.ts @@ -1,7 +1,11 @@ interface IProjectItem { title: string, image: string, - id: string + id: string, + subscriptionUntil: string, + subscriptionSessionCount: number, + applicationVersion: string + } export default IProjectItem \ No newline at end of file