+
{Props.list.length ? (
@@ -118,7 +131,9 @@ export const SelectDevice: React.FC = (Props) => {
>
))
) : (
- Нет устройств
+
+ Нет устройств
+
)}
diff --git a/src/features/EnterProfile/index.ts b/src/features/EnterProfile/index.ts
new file mode 100644
index 0000000..7a18b97
--- /dev/null
+++ b/src/features/EnterProfile/index.ts
@@ -0,0 +1 @@
+export { EnterProfileButton } from "./ui/EnterProfileButton";
diff --git a/src/features/EnterProfile/ui/EnterProfileButton.tsx b/src/features/EnterProfile/ui/EnterProfileButton.tsx
new file mode 100644
index 0000000..a6b42f9
--- /dev/null
+++ b/src/features/EnterProfile/ui/EnterProfileButton.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import { styled } from "styled-components";
+import settingsIcon from "../../../../public/icons/setting-mini.svg";
+import Paragraph from "../../../shared/ui/Paragraph";
+
+const Container = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ color: inherit;
+`;
+
+export const EnterProfileButton: React.FC = () => {
+ function enterProfile() {
+ window.location.href = "/profile";
+ }
+
+ return (
+
+
+ Настройки профиля
+
+ );
+};
diff --git a/src/features/createRoom/model/index.ts b/src/features/createRoom/model/index.ts
index 865e782..ff15fbf 100644
--- a/src/features/createRoom/model/index.ts
+++ b/src/features/createRoom/model/index.ts
@@ -1,34 +1,9 @@
import { IUser } from "../../../shared/api/models";
-import user from "../../../pages/Lobby/store/user";
-
-export const AddUserThunk = (fullname: any, photo_url: string, email: any) => {
- const API = String(import.meta.env.VITE_API);
-
- const newUser = {
- full_name: fullname,
- photo_url: photo_url,
- email: email
- }
-
- fetch(`${API}/users`, {
- method : 'POST',
- headers: {
- 'Content-type': 'application/json',
- },
- body : JSON.stringify(newUser),
- })
- .then(response => response.text())
- .then(response => {
- response = JSON.parse(response);
- console.log(response);
- user.addUser(JSON.parse(response));
- })
-}
export const CreateThunk = (event: any, title: string, isPublic: boolean, user: IUser) => {
event.preventDefault();
- AddUserThunk(user?.name, 'test', user?.email);
const API = String(import.meta.env.VITE_API);
+
console.log(user?.email);
const newRoom = {
diff --git a/src/features/editRoom/model/delete.ts b/src/features/editRoom/model/delete.ts
index b4bf2d0..4da660c 100644
--- a/src/features/editRoom/model/delete.ts
+++ b/src/features/editRoom/model/delete.ts
@@ -1,12 +1,16 @@
-export const DeleteThunk= (id: number) => {
+export const DeleteThunk= (id: number, email: any) => {
const API = String(import.meta.env.VITE_API);
- fetch(`${API}/channels/`, {
+ const info = {
+ user_email: String(email)
+ }
+
+ fetch(`${API}/channels/${id}`, {
method : 'DELETE',
headers: {
'Content-type': 'application/json',
},
- body : JSON.stringify({id}),
+ body : JSON.stringify(info),
})
.then(response => response.text())
.then(response => {
diff --git a/src/features/editRoom/model/index.ts b/src/features/editRoom/model/index.ts
index 4085771..b391514 100644
--- a/src/features/editRoom/model/index.ts
+++ b/src/features/editRoom/model/index.ts
@@ -1,13 +1,19 @@
-export const EditThunk= (event: any, id: number, title: string, isPublic: boolean) => {
+import { IRoom } from '../../../entities/room/api/models';
+
+export const EditThunk= (event: any, room: IRoom, title: string, isPublic: boolean, email: any) => {
event.preventDefault();
const API = String(import.meta.env.VITE_API);
const editedRoom = {
- name: title,
- public: isPublic,
+ user_email: email,
+ title: title, //change
+ photo_url: room.photo_url,
+ url: room.url,
+ isPublic: isPublic, //change
+ isActive: room.isActive
}
- fetch(`${API}/channels/${id}`, {
+ fetch(`${API}/channels/${room.id}`, {
method : 'PUT',
headers: {
'Content-type': 'application/json',
diff --git a/src/features/editRoom/ui/EditRoomForm.tsx b/src/features/editRoom/ui/EditRoomForm.tsx
index eb6ca5b..2b99fc9 100644
--- a/src/features/editRoom/ui/EditRoomForm.tsx
+++ b/src/features/editRoom/ui/EditRoomForm.tsx
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { IRoom } from '../../../entities/room/api/models';
import { EditThunk } from '../model';
import { DeleteThunk } from '../model/delete';
+import { observer } from 'mobx-react-lite';
import styled from 'styled-components';
import LobbyFormLayout from '../../../widgets/layout/LobbyFormLayout';
import Input from '../../../shared/ui/Input';
@@ -9,6 +10,7 @@ import SwitchToggle from '../../../shared/ui/switchToggle/SwitchToggle';
import FormButton from '../../../shared/ui/formButton/FormButton';
import avatar from '../../../../public/icons/avatar.svg';
import deleteIcon from '../../../../public/icons/delete.svg';
+import { useAuth0 } from "@auth0/auth0-react";
const Form = styled.form`
display: flex;
@@ -60,16 +62,17 @@ interface Props {
room: IRoom,
}
-export const EditRoomForm: React.FC
= ({ room }) => {
+export const EditRoomForm: React.FC = observer(({ room }) => {
+ const { user } = useAuth0();
const [title, setTitle] = useState(room.title);
const [isPublic, setIsPublic] = useState(room.isPublic);
function editRoom(event: any) {
- EditThunk(event, room.id, title, isPublic);
+ EditThunk(event, room, title, isPublic, user?.email);
}
function deleteRoom() {
- DeleteThunk(room.id);
+ DeleteThunk(room.id, user?.email);
}
return (
@@ -94,4 +97,4 @@ export const EditRoomForm: React.FC = ({ room }) => {
)
-}
+})
diff --git a/src/features/editUser/index.ts b/src/features/editUser/index.ts
new file mode 100644
index 0000000..f33886e
--- /dev/null
+++ b/src/features/editUser/index.ts
@@ -0,0 +1 @@
+export { EditUserForm } from "./ui/EditUserForm";
diff --git a/src/features/editUser/ui/EditUserForm.tsx b/src/features/editUser/ui/EditUserForm.tsx
new file mode 100644
index 0000000..90b19db
--- /dev/null
+++ b/src/features/editUser/ui/EditUserForm.tsx
@@ -0,0 +1,112 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+import styles from "./styles.module.css";
+import ProfileFormLayout from "../../../widgets/layout/ProfileFormLayout";
+import { useAuth0 } from "@auth0/auth0-react";
+import avatarDefault from "../../../../public/icons/avatar.svg";
+import FormButton from "../../../shared/ui/formButton/FormButton";
+import profileFormState from "../../../pages/Profile/store/profileFormState";
+import { observer } from "mobx-react-lite";
+
+const Form = styled.form`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: -2px;
+ bottom: -2px;
+ left: -2px;
+ right: -2px;
+ border-radius: 12px;
+ background: linear-gradient(
+ 223deg,
+ rgba(255, 178, 64, 0.9) 0%,
+ rgba(216, 97, 196, 0.9) 50.52%,
+ rgba(23, 94, 241, 0.9) 100%
+ );
+ z-index: -1;
+ }
+`;
+
+export const EditUserForm: React.FC = observer(() => {
+ const { user } = useAuth0();
+ const [avatar, setAvatar] = useState(user?.picture || avatarDefault);
+ const [name, setName] = useState(user?.name);
+
+ const sendAccess = () => {
+ profileFormState.confirmEmail();
+ };
+
+ const saveChanges = () => {
+ profileFormState.closeEditForm();
+ };
+
+ const onImageChange = (event: React.ChangeEvent) => {
+ if (event.target.files && event.target.files[0]) {
+ setAvatar(URL.createObjectURL(event.target.files[0]));
+ }
+ };
+
+ return (
+
+
+
+ );
+});
diff --git a/src/features/editUser/ui/styles.module.css b/src/features/editUser/ui/styles.module.css
new file mode 100644
index 0000000..d3e9e4a
--- /dev/null
+++ b/src/features/editUser/ui/styles.module.css
@@ -0,0 +1,71 @@
+.user {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ gap: 20px;
+}
+
+.avatar {
+ width: 86px;
+ height: 86px;
+ border-radius: 10px;
+ border: 2px dashed #175ef1;
+ position: relative;
+}
+
+.inputAvatar {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ color: transparent;
+
+ &:hover {
+ cursor: pointer;
+ }
+
+ &::file-selector-button {
+ display: none;
+ }
+}
+
+.info {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+}
+
+.name {
+ width: 100%;
+ font-size: 22px;
+ font-weight: 500;
+}
+
+.email {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.emailText {
+ font-size: 20px;
+ font-weight: 300;
+ line-height: normal;
+}
+
+.accessEmail {
+ font-size: 20px;
+ font-weight: 300;
+ line-height: normal;
+}
+
+.accessText {
+ color: var(--red, #f95a39);
+
+ &:hover {
+ text-decoration: underline;
+ cursor: pointer;
+ }
+}
diff --git a/src/features/logout/ui/LogoutButton.tsx b/src/features/logout/ui/LogoutButton.tsx
index 7f41339..8c6f0ba 100644
--- a/src/features/logout/ui/LogoutButton.tsx
+++ b/src/features/logout/ui/LogoutButton.tsx
@@ -1,20 +1,32 @@
-import React from 'react';
+import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
-import Paragraph from '../../../shared/ui/Paragraph';
+import Paragraph from "../../../shared/ui/Paragraph";
+import logoutIcon from "../../../../public/icons/logout.svg";
+import { styled } from "styled-components";
+
+const Container = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ color: inherit;
+`;
export const LogoutButton: React.FC = () => {
- const { logout } = useAuth0();
+ const { logout } = useAuth0();
- function logoutFunc(event : any) {
- event.preventDefault();
- logout({ logoutParams: { returnTo: window.location.origin } });
- }
+ function logoutFunc(event: any) {
+ event.preventDefault();
+ logout({ logoutParams: { returnTo: window.location.origin } });
+ }
return (
-
- )
-}
+
+
+
+
+ );
+};
diff --git a/src/pages/CallPageCustomUI/CallPage.tsx b/src/pages/CallPageCustomUI/CallPage.tsx
index 89f2f30..6d80595 100644
--- a/src/pages/CallPageCustomUI/CallPage.tsx
+++ b/src/pages/CallPageCustomUI/CallPage.tsx
@@ -8,6 +8,8 @@ import avatar from "../../../public/icons/avatar.svg";
import Sidebar from "../../widgets/layout/Sidebar/Sidebar";
import storeSidebar from "./store/sidebarState";
import { observer } from "mobx-react-lite";
+import settingsState from "./store/settingsState";
+import SettingsCallPopup from "../../widgets/layout/SettingsCallPopup/SettingsCallPopup";
const Container = styled.div`
width: 100%;
@@ -30,6 +32,17 @@ const Content = styled.div`
transition: all 0.3s ease-out;
`;
+const Overlay = styled.div`
+ background: white;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0.4;
+ z-index: 100;
+`;
+
const peopleList: IUser[] = [
{
email: "jjj",
@@ -178,6 +191,10 @@ const peopleList: IUser[] = [
];
const CallPage: React.FC = observer(() => {
+ function closePopup() {
+ settingsState.closeSettings();
+ }
+
return (
{
}
>
-
+
+ {settingsState.isActive && }
+ {settingsState.isActive && }
);
});
diff --git a/src/pages/CallPageCustomUI/store/settingsState.ts b/src/pages/CallPageCustomUI/store/settingsState.ts
new file mode 100644
index 0000000..0eddd3d
--- /dev/null
+++ b/src/pages/CallPageCustomUI/store/settingsState.ts
@@ -0,0 +1,28 @@
+import { makeAutoObservable } from "mobx";
+
+class SettingsState {
+ isActive = false;
+ selected = "My";
+
+ constructor() {
+ makeAutoObservable(this);
+ }
+
+ openSettings() {
+ this.isActive = true;
+ }
+
+ closeSettings() {
+ this.isActive = false;
+ }
+
+ selectClass() {
+ this.selected = "Class";
+ }
+
+ selectMy() {
+ this.selected = "My";
+ }
+}
+
+export default new SettingsState();
diff --git a/src/pages/Join/Join.tsx b/src/pages/Join/Join.tsx
index 91d57dd..2e0419a 100644
--- a/src/pages/Join/Join.tsx
+++ b/src/pages/Join/Join.tsx
@@ -9,15 +9,24 @@ import { EnterClassForm } from "../../features/EnterClass/index.ts";
import FunctionsList from "../../widgets/FunctionsList/FunctionsList.tsx";
import functions from "../../widgets/FunctionsList/functionsObject.tsx";
import ProfilePanel from "../../widgets/ProfilePanel/ProfilePanel.tsx"
+import { useAuth0 } from "@auth0/auth0-react";
+import { useAddUser } from "../../entities/user/api/useAddUser.ts";
const Join: React.FC = () => {
+ const { isAuthenticated, user } = useAuth0();
+
+ if (isAuthenticated) {
+ useAddUser(user?.name, 'test', user?.email);
+ }
return (
-
- Сетевой учебный класс
+
+
+
Сетевой учебный класс
+
diff --git a/src/pages/Join/styles.module.css b/src/pages/Join/styles.module.css
index 2fd1f50..200d2fb 100644
--- a/src/pages/Join/styles.module.css
+++ b/src/pages/Join/styles.module.css
@@ -19,10 +19,17 @@
width: 100%;
display: flex;
align-items: center;
+ justify-content: space-between;
margin-bottom: 100px;
position: relative;
}
+.logo {
+ display: flex;
+ align-items: center;
+ gap: 24px;
+}
+
.header > img {
margin-right: 24px;
}
diff --git a/src/pages/Lobby/Lobby.tsx b/src/pages/Lobby/Lobby.tsx
index 10602ed..1e3b49a 100644
--- a/src/pages/Lobby/Lobby.tsx
+++ b/src/pages/Lobby/Lobby.tsx
@@ -1,21 +1,26 @@
import React from 'react';
+import { observer } from 'mobx-react-lite';
+import navbarState from './store/navbarState';
+import roomsFormState from './store/roomsFormState';
import { useRoomsList } from '../../entities/room/api/useRoomsList';
import Header from '../../widgets/layout/Header';
import Navbar from '../../widgets/layout/Navbar';
+import { CreateRoomForm } from '../../features/createRoom';
import RoomsList from '../../widgets/RoomsList';
-import user from './store/user';
-const Lobby: React.FC = () => {
+const Lobby: React.FC = observer(() => {
const { rooms, loading, error } = useRoomsList();
- console.log(user.state);
+
+ const roomsFormStateLS = localStorage.getItem("trigger");
return (
<>
-
+
+ {roomsFormState.state || roomsFormStateLS === 'create' && navbarState.state === 'my' ? : null}
>
)
-}
+})
export default Lobby;
diff --git a/src/pages/Lobby/LobbyAccess.tsx b/src/pages/Lobby/LobbyAccess.tsx
deleted file mode 100644
index f7b9593..0000000
--- a/src/pages/Lobby/LobbyAccess.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react';
-import { useRoomsList } from '../../entities/room/api/useRoomsList';
-import Header from '../../widgets/layout/Header';
-import Navbar from '../../widgets/layout/Navbar';
-import RoomsList from '../../widgets/RoomsList';
-
-const LobbyAccess: React.FC = () => {
- const { rooms, loading, error } = useRoomsList();
-
- return (
- <>
-
-
-
- >
- )
-}
-
-export default LobbyAccess;
diff --git a/src/pages/Lobby/LobbyMy.tsx b/src/pages/Lobby/LobbyMy.tsx
deleted file mode 100644
index bb74a69..0000000
--- a/src/pages/Lobby/LobbyMy.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import React, { useEffect } from "react";
-import { useRoomsList } from '../../entities/room/api/useRoomsList';
-import Header from "../../widgets/layout/Header";
-import Navbar from "../../widgets/layout/Navbar";
-import { CreateRoomForm } from "../../features/createRoom/index.ts";
-import RoomsList from "../../widgets/RoomsList";
-import { observer } from "mobx-react-lite";
-import roomsFormState from "./store/roomsFormState.ts";
-// import { useAuth0 } from "@auth0/auth0-react";
-
-const LobbyMy: React.FC = observer(() => {
- const { rooms, loading, error } = useRoomsList();
-
- useEffect(() => {
- if (localStorage.getItem("trigger") === "create") {
- roomsFormState.openCreateForm();
- localStorage.removeItem("trigger");
- }
- }, []);
-
- return (
- <>
-
-
- {roomsFormState.state === "create" ? : <>>}
-
- >
- );
-});
-
-export default LobbyMy;
diff --git a/src/pages/Lobby/store/navbarState.ts b/src/pages/Lobby/store/navbarState.ts
new file mode 100644
index 0000000..64a9a13
--- /dev/null
+++ b/src/pages/Lobby/store/navbarState.ts
@@ -0,0 +1,36 @@
+import { makeAutoObservable } from "mobx";
+
+const roomsFormStateLS = localStorage.getItem("trigger");
+
+function defaultState() {
+ if (roomsFormStateLS === 'create') {
+ return 'my';
+ }
+
+ if (roomsFormStateLS === 'all') {
+ return 'all';
+ }
+}
+
+console.log(defaultState());
+
+class NavbarState {
+ state = defaultState();
+ constructor() {
+ makeAutoObservable(this)
+ }
+
+ openAll() {
+ this.state = 'all';
+ }
+
+ openAccess() {
+ this.state = 'access';
+ }
+
+ openMy() {
+ this.state = 'my';
+ }
+}
+
+export default new NavbarState();
\ No newline at end of file
diff --git a/src/pages/Lobby/store/user.ts b/src/pages/Lobby/store/userState.ts
similarity index 82%
rename from src/pages/Lobby/store/user.ts
rename to src/pages/Lobby/store/userState.ts
index 9f724c4..03b4dd4 100644
--- a/src/pages/Lobby/store/user.ts
+++ b/src/pages/Lobby/store/userState.ts
@@ -1,7 +1,7 @@
import { makeAutoObservable } from "mobx";
import { IUser } from "../../../entities/user/api/models";
-class User {
+class UserState {
state = {};
constructor() {
makeAutoObservable(this)
@@ -12,4 +12,4 @@ state = {};
}
}
-export default new User();
+export default new UserState();
diff --git a/src/pages/Profile/Profile.tsx b/src/pages/Profile/Profile.tsx
new file mode 100644
index 0000000..48f49f2
--- /dev/null
+++ b/src/pages/Profile/Profile.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import { styled } from "styled-components";
+import Header from "../../widgets/layout/Header";
+import UserCard from "../../entities/user/ui/UserCard";
+import Statistics from "../../widgets/Statistics/Statistics";
+import profileFormState from "./store/profileFormState";
+import { EditUserForm } from "../../features/editUser";
+import { observer } from "mobx-react-lite";
+
+const Container = styled.div``;
+
+const Title = styled.div`
+ color: #000;
+ font-family: var(--font);
+ font-size: 28px;
+ font-weight: 500;
+ margin: 84px 0 34px 123px;
+`;
+
+const ProfileCard = styled.div`
+ margin: 0 121px 73px 123px;
+`;
+
+const Profile: React.FC = observer(() => {
+ return (
+
+
+ Мой профиль
+
+ {profileFormState.state ? : }
+
+
+
+ );
+});
+
+export default Profile;
diff --git a/src/pages/Profile/store/profileFormState.tsx b/src/pages/Profile/store/profileFormState.tsx
new file mode 100644
index 0000000..1f62fe8
--- /dev/null
+++ b/src/pages/Profile/store/profileFormState.tsx
@@ -0,0 +1,23 @@
+import { makeAutoObservable } from "mobx";
+
+class FormState {
+ state = "";
+ isEmailConfirmed = false;
+ constructor() {
+ makeAutoObservable(this);
+ }
+
+ openEditForm() {
+ this.state = "edit";
+ }
+
+ closeEditForm() {
+ this.state = "";
+ }
+
+ confirmEmail() {
+ this.isEmailConfirmed = true;
+ }
+}
+
+export default new FormState();
diff --git a/src/shared/ui/Select.tsx b/src/shared/ui/Select.tsx
index 92b52c5..ea72e30 100644
--- a/src/shared/ui/Select.tsx
+++ b/src/shared/ui/Select.tsx
@@ -1,5 +1,5 @@
-import React from 'react';
-import styled from 'styled-components';
+import React from "react";
+import styled from "styled-components";
const Container = styled.div`
position: absolute;
@@ -8,29 +8,35 @@ const Container = styled.div`
z-index: 1;
padding: 20px 16px 16px;
- border-radius: 10px ;
+ border-radius: 10px;
background: var(--white);
box-shadow: 5px 5px 10px 0px var(--grey_5);
- transition: all .3s ease;
-`
+ transition: all 0.3s ease;
-const Content = styled.div`
+ &:hover {
+ cursor: default;
+ }
+`;
-`
+const Content = styled.div``;
interface Props {
- children?: React.ReactNode,
- active: boolean,
+ children?: React.ReactNode;
+ active: boolean;
}
const Select: React.FC = ({ children, active }) => {
return (
-
-
- {children}
-
+
+ {children}
- )
-}
+ );
+};
-export default Select
\ No newline at end of file
+export default Select;
diff --git a/src/shared/ui/Tooltip.tsx b/src/shared/ui/Tooltip.tsx
index e6b660f..7ca4e51 100644
--- a/src/shared/ui/Tooltip.tsx
+++ b/src/shared/ui/Tooltip.tsx
@@ -17,6 +17,7 @@ const Content = styled.div`
box-shadow: 0px 2px 6px 0px #c5ccd5;
border-radius: 4px;
+ white-space: nowrap;
font-family: var(--font);
font-size: 14px;
font-style: normal;
@@ -38,9 +39,10 @@ const Content = styled.div`
interface Props {
active: boolean;
children: React.ReactNode;
+ message: string;
}
-const Tooltip: React.FC = ({ active, children }) => {
+const Tooltip: React.FC = ({ active, children, message }) => {
return (
= ({ active, children }) => {
: { opacity: 0, visibility: "hidden" }
}
>
- Ссылка скопирована!
+ {message}
{children}
diff --git a/src/shared/ui/cardButton/CardButton.tsx b/src/shared/ui/cardButton/CardButton.tsx
new file mode 100644
index 0000000..d2b75ac
--- /dev/null
+++ b/src/shared/ui/cardButton/CardButton.tsx
@@ -0,0 +1,33 @@
+import React from "react";
+import styled from "styled-components";
+
+const Button = styled.button`
+ display: flex;
+ padding: 10px;
+ justify-content: center;
+ align-items: center;
+ border-radius: 8px;
+ border: 1px solid var(--blue, #175ef1);
+ background: var(--white, #fff);
+ color: var(--blue, #175ef1);
+ font-size: 18px;
+ font-weight: 400;
+ line-height: normal;
+ transition: all 0.3s ease;
+
+ &:hover {
+ color: var(--white);
+ background: var(--blue, #175ef1);
+ }
+`;
+
+interface Props {
+ children?: string;
+ onClick?: () => void;
+}
+
+const CardButton: React.FC = ({ children, onClick }) => {
+ return ;
+};
+
+export default CardButton;
diff --git a/src/shared/ui/checkBox/CheckBox.tsx b/src/shared/ui/checkBox/CheckBox.tsx
new file mode 100644
index 0000000..9d09a79
--- /dev/null
+++ b/src/shared/ui/checkBox/CheckBox.tsx
@@ -0,0 +1,58 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+import check from "../../../../public/icons/check_small.svg";
+
+const Container = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 15px;
+`;
+
+const Input = styled.input`
+ width: 18px;
+ height: 18px;
+ border-radius: 2px;
+ border: 1.5px solid var(--grey-4, #c5ccd5);
+
+ &:checked {
+ background: var(--blue, #175ef1) url(${check}) center no-repeat;
+ }
+ &:hover {
+ cursor: pointer;
+ }
+`;
+
+const Title = styled.div`
+ color: var(--grey-3, #a0afc1);
+ font-family: var(--font);
+ font-size: 16px;
+ font-weight: 400;
+`;
+
+interface Props {
+ text: string;
+}
+
+const CheckBox: React.FC = ({ text }) => {
+ const [selected, setSelected] = useState(true);
+
+ function changeSelected() {
+ selected ? setSelected(false) : setSelected(true);
+ }
+
+ return (
+
+
+
+ {text}
+
+
+ );
+};
+
+export default CheckBox;
diff --git a/src/shared/ui/loader/Loader.tsx b/src/shared/ui/loader/Loader.tsx
index a2fef6c..a314ba4 100644
--- a/src/shared/ui/loader/Loader.tsx
+++ b/src/shared/ui/loader/Loader.tsx
@@ -1,13 +1,32 @@
import React from "react";
-import styles from "./styles.module.css";
+// import styles from "./styles.module.css";
+import loader from '../../../../public/icons/loader.gif';
+import styled from 'styled-components';
+
+const Page = styled.div`
+ width: 100wh;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #fff;
+`
+
+const Gif = styled.img`
+ width: 200px;
+ height: 200px;
+`
const Loader: React.FC = () => {
return (
-
+ //
+
+
+
);
};
diff --git a/src/shared/ui/switchButton/SwitchButton.tsx b/src/shared/ui/switchButton/SwitchButton.tsx
new file mode 100644
index 0000000..19e1161
--- /dev/null
+++ b/src/shared/ui/switchButton/SwitchButton.tsx
@@ -0,0 +1,20 @@
+import React, { useState } from "react";
+import styles from "./styles.module.css";
+import classNames from "classnames";
+
+const SwitchButton: React.FC = () => {
+ const [selected, setSelected] = useState(true);
+
+ function changeSelected() {
+ selected ? setSelected(false) : setSelected(true);
+ }
+
+ return (
+
+ );
+};
+
+export default SwitchButton;
diff --git a/src/shared/ui/switchButton/styles.module.css b/src/shared/ui/switchButton/styles.module.css
new file mode 100644
index 0000000..335aa23
--- /dev/null
+++ b/src/shared/ui/switchButton/styles.module.css
@@ -0,0 +1,28 @@
+.switchBtn {
+ display: inline-block;
+ width: 36px;
+ height: 20px;
+ border-radius: 15px;
+ background: var(--grey_4);
+ cursor: pointer;
+ position: relative;
+ transition-duration: 300ms;
+}
+.switchBtn::after {
+ content: "";
+ height: 17px;
+ width: 16px;
+ border-radius: 50%;
+ background: #fff;
+ top: 1.5px;
+ left: 1.5px;
+ transition-duration: 300ms;
+ position: absolute;
+ z-index: 1;
+}
+.switchOn {
+ background: var(--blue);
+}
+.switchOn::after {
+ left: 18.5px;
+}
diff --git a/src/widgets/CallControllers.tsx b/src/widgets/CallControllers.tsx
index d7c4a1f..b08a0ee 100644
--- a/src/widgets/CallControllers.tsx
+++ b/src/widgets/CallControllers.tsx
@@ -1,42 +1,42 @@
-import React from 'react';
-import styled from 'styled-components';
-import ControllersWrapper from './layout/ControllersWrapper';
-import { MicrophoneController } from '../features/MicrophoneController';
-import { CameraController } from '../features/CameraController';
-import { RecordController } from '../features/RecordController';
-import { HandController } from '../features/HandController/ui/HandController';
-import { ScreenController } from '../features/ScreenController';
-import { MenuController } from '../features/ControllersMenu';
-import { LeaveCall } from '../features/LeaveCall';
+import React from "react";
+import styled from "styled-components";
+import ControllersWrapper from "./layout/ControllersWrapper";
+import { MicrophoneController } from "../features/MicrophoneController";
+import { CameraController } from "../features/CameraController";
+import { RecordController } from "../features/RecordController";
+import { HandController } from "../features/HandController/ui/HandController";
+import { ScreenController } from "../features/ScreenController";
+import { MenuController } from "../features/ControllersMenu";
+import { LeaveCall } from "../features/LeaveCall";
const Left = styled.div`
display: flex;
gap: 20px;
justify-content: space-between;
-`
+`;
const Center = styled.div`
display: flex;
gap: 20px;
justify-content: space-between;
-`
+`;
const CallControllers: React.FC = () => {
return (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
- )
-}
+ );
+};
-export default CallControllers
\ No newline at end of file
+export default CallControllers;
diff --git a/src/widgets/FunctionsList/functionsObject.tsx b/src/widgets/FunctionsList/functionsObject.tsx
index b0d60b9..808d94f 100644
--- a/src/widgets/FunctionsList/functionsObject.tsx
+++ b/src/widgets/FunctionsList/functionsObject.tsx
@@ -10,9 +10,9 @@ const functions: IFunction[] = [
{
icon: createClass,
iconActive: createClassActive,
- title: "Новый класс",
+ title: "Мои классы",
description: "Создать свой класс и провести занятие онлайн",
- link: "/lobby/my",
+ link: "/lobby",
onClick: () => {
localStorage.setItem("trigger", "create");
},
@@ -23,13 +23,16 @@ const functions: IFunction[] = [
title: "Поиск",
description: "Найти класс и получить новые знания",
link: "/lobby",
+ onClick: () => {
+ localStorage.setItem("trigger", "all");
+ },
},
{
icon: settings,
iconActive: settingsActive,
title: "Настройки",
description: "Редактировать свой профиль и классы",
- link: "/",
+ link: "/profile",
},
];
diff --git a/src/widgets/ProfilePanel/ProfilePanel.tsx b/src/widgets/ProfilePanel/ProfilePanel.tsx
index e971b8a..85f304e 100644
--- a/src/widgets/ProfilePanel/ProfilePanel.tsx
+++ b/src/widgets/ProfilePanel/ProfilePanel.tsx
@@ -1,13 +1,12 @@
-import React, { useState } from 'react';
-import styled from 'styled-components';
-import Select from '../../shared/ui/Select';
-import { LogoutButton } from '../../features/logout';
+import React, { useState } from "react";
+import styled from "styled-components";
+import Select from "../../shared/ui/Select";
+import { LogoutButton } from "../../features/logout";
import avatarIcon from "../../../public/icons/avatar.svg";
import selectIcon from "../../../public/icons/select.svg";
-import settingsIcon from "../../../public/icons/setting-mini.svg";
-import logoutIcon from "../../../public/icons/logout.svg";
import { useAuth0 } from "@auth0/auth0-react";
-import Paragraph from '../../shared/ui/Paragraph';
+import Paragraph from "../../shared/ui/Paragraph";
+import { EnterProfileButton } from "../../features/EnterProfile";
const Container = styled.div`
position: relative;
@@ -17,7 +16,7 @@ const Container = styled.div`
align-items: center;
gap: 15px;
- &:hover{
+ &:hover {
cursor: pointer;
}
`;
@@ -26,7 +25,7 @@ const Avatar = styled.img`
width: 44px;
height: 44px;
border-radius: 10px;
-`
+`;
const Text = styled.div`
display: flex;
@@ -43,7 +42,7 @@ const Text = styled.div`
background: linear-gradient(90deg, transparent 0, #fff 100%);
content: "";
}
-`
+`;
const Button = styled.button`
display: flex;
@@ -51,53 +50,56 @@ const Button = styled.button`
align-items: center;
width: 34px;
height: 34px;
-`
+`;
-const SelectLink = styled.a`
- display: flex;
- gap: 8px;
- align-items: center;
+const SelectLink = styled.div`
color: inherit;
+
+ &:hover {
+ cursor: pointer;
+ }
`;
const Divider = styled.div`
margin: 10px 0;
- width: 192px;
+ width: 100%;
height: 0.5px;
background: var(--grey_5);
`;
const ProfilePanel: React.FC = () => {
- const [selectActive, setSelectActive] = useState(false);
- const { user, isAuthenticated } = useAuth0();
-
- function changeSelectVisibility() {
- setSelectActive(!selectActive);
- }
+ const [selectActive, setSelectActive] = useState(false);
+ const { user, isAuthenticated } = useAuth0();
+
+ function changeSelectVisibility() {
+ setSelectActive(!selectActive);
+ }
return (
-
-
-
- {isAuthenticated ? {user?.name} : Loading...}
-
-
+
+
+
+ {isAuthenticated ? (
+ {user?.name}
+ ) : (
+ Loading...
+ )}
+
+
-
-
- )
+
+
+ );
};
export default ProfilePanel;
diff --git a/src/widgets/RoomsList.tsx b/src/widgets/RoomsList.tsx
index aa92820..30a0582 100644
--- a/src/widgets/RoomsList.tsx
+++ b/src/widgets/RoomsList.tsx
@@ -37,8 +37,7 @@ const Container = styled.div`
const Header = styled.div`
display: flex;
- width: 80%;
- justify-content: space-between;
+ width: 100%;
align-items: center;
margin: 0 auto 27px;
`
@@ -76,15 +75,13 @@ const RoomsList: React.FC = observer(({ rooms, loading, error }) => {
console.log(searchedRooms);
};
- console.log(rooms);
-
return (
- Название
- Владелец
- Статус
- Доступ
+ Название
+ Владелец
+ Статус
+ Доступ
{searchedRooms.length > 0 ?
<>
diff --git a/src/widgets/SettingsClass/SettingsClass.tsx b/src/widgets/SettingsClass/SettingsClass.tsx
new file mode 100644
index 0000000..c7dd78b
--- /dev/null
+++ b/src/widgets/SettingsClass/SettingsClass.tsx
@@ -0,0 +1,70 @@
+import React from "react";
+import styled from "styled-components";
+import { SettingClassLayout } from "../layout/SettingClassLayout";
+import SwitchButton from "../../shared/ui/switchButton/SwitchButton";
+
+const Setting = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 15px;
+`;
+
+const SettingText = styled.div`
+ color: var(--black, #000);
+ font-family: var(--font);
+ font-size: 16px;
+ font-weight: 400;
+ line-height: normal;
+`;
+
+const SettingsClass: React.FC = () => {
+ return (
+ <>
+
+ <>
+
+
+ Разрешить участникам видеть все демонстрации
+
+
+
+
+
+ Разрешить участникам выбирать вкладку для показа
+
+
+
+ >
+
+
+ <>
+
+ Разрешить участникам использовать камеру
+
+
+ >
+
+
+ <>
+
+
+ Разрешить участникам использовать микрофон
+
+
+
+ >
+
+
+ <>
+
+ Разрешить участникам записывать встречи
+
+
+ >
+
+ >
+ );
+};
+
+export default SettingsClass;
diff --git a/src/widgets/SettingsMy/SettingsMy.tsx b/src/widgets/SettingsMy/SettingsMy.tsx
new file mode 100644
index 0000000..1ccde53
--- /dev/null
+++ b/src/widgets/SettingsMy/SettingsMy.tsx
@@ -0,0 +1,104 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+import { SelectDevice } from "../../features/DeviceSetting";
+import { useAuth0 } from "@auth0/auth0-react";
+
+const Input = styled.input`
+ display: flex;
+ width: 100%;
+ min-height: 54px;
+ padding: 4px 0px 4px 16px;
+ align-items: center;
+ border-radius: 10px;
+ background: #fff;
+ border: 1.5px solid var(--blue);
+ margin-bottom: 10px;
+ color: var(--black, #000);
+ font-family: var(--font);
+ font-size: 20px;
+ font-weight: 400;
+ line-height: 24px;
+ letter-spacing: 0.5px;
+`;
+
+const Title = styled.label`
+ position: absolute;
+ top: -9px;
+ left: 14px;
+ color: var(--blue, #175ef1);
+ background: white;
+ padding: 0 5px;
+ font-family: var(--font);
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 16px;
+ letter-spacing: 0.4px;
+`;
+
+const stylesText = {
+ color: "var(--black, #000)",
+ fontSize: "20px",
+ fontWeight: "600",
+ lineHeight: "normal",
+};
+
+const stylesBlock = {
+ border: "1px solid var(--grey-5, #D5DEE8)",
+ boxShadow: "none",
+};
+
+const stylesList = {
+ border: "1px solid var(--grey-5, #D5DEE8)",
+ boxShadow: "none",
+};
+
+const stylesContainer = {
+ flex: "0 0",
+};
+
+const SettingsMy: React.FC = () => {
+ const { user } = useAuth0();
+ const [name, setName] = useState(user?.name);
+
+ return (
+ <>
+
+
Имя в классе
+ ) =>
+ setName(e.target.value)
+ }
+ />
+
+
+
+
+ >
+ );
+};
+
+export default SettingsMy;
diff --git a/src/widgets/Statistics/Statistics.tsx b/src/widgets/Statistics/Statistics.tsx
new file mode 100644
index 0000000..8eb6c5e
--- /dev/null
+++ b/src/widgets/Statistics/Statistics.tsx
@@ -0,0 +1,66 @@
+import React from "react";
+import styled from "styled-components";
+
+const Container = styled.div`
+ display: grid;
+ grid-template-columns: repeat(3, max-content);
+ justify-content: space-between;
+ gap: 30px;
+ margin: 0 136px 0 144px;
+ color: #000;
+ font-family: var(--font);
+ line-height: normal;
+`;
+
+const StatisticsBlock = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ gap: 10px;
+`;
+
+const StatisticsTitle = styled.div`
+ font-size: 22px;
+ font-weight: 500;
+`;
+
+const StatisticsText = styled.div`
+ font-size: 20px;
+ font-weight: 300;
+`;
+
+const Statistics: React.FC = () => {
+ return (
+
+
+ Дата регистрации
+ 08.08.2023
+
+
+ Дата последней онлайн-встречи
+ 09.08.2023
+
+
+ Частота проведения встреч
+ 2.8 встреч в месяц
+
+
+ Всего участников
+ 1784
+
+
+ Всего моих классов
+ 15
+
+
+
+ Всего онлайн участников в моих классах
+
+ 12
+
+
+ );
+};
+
+export default Statistics;
diff --git a/src/widgets/UserGrid/UserGrid.tsx b/src/widgets/UserGrid/UserGrid.tsx
index fce7228..bd069e7 100644
--- a/src/widgets/UserGrid/UserGrid.tsx
+++ b/src/widgets/UserGrid/UserGrid.tsx
@@ -64,7 +64,7 @@ const ShowMoreButton = styled.button`
position: absolute;
top: 50%;
transform: translate(0, -50%);
- z-index: 1000;
+ z-index: 10;
&:hover {
cursor: pointer;
diff --git a/src/widgets/layout/Navbar.tsx b/src/widgets/layout/Navbar.tsx
index 8c87428..c7d9036 100644
--- a/src/widgets/layout/Navbar.tsx
+++ b/src/widgets/layout/Navbar.tsx
@@ -1,10 +1,12 @@
// import React from 'react';
import styled from 'styled-components';
+import { observer } from 'mobx-react-lite';
import { AddRoomButton } from '../../features/AddRoom.tsx/index.ts';
import { SearchInput } from '../../features/Search/index.ts';
import roomsFormState from '../../pages/Lobby/store/roomsFormState.ts';
import roomsState from '../../pages/Lobby/store/roomsState.ts';
import editIcon from '../../../public/icons/edit.svg';
+import navbarState from '../../pages/Lobby/store/navbarState.ts';
const Container = styled.div`
display: flex;
@@ -21,7 +23,7 @@ const Left = styled.div`
justify-content: space-between;
`
-const Link = styled.a`
+const Link = styled.button`
font-family: var(--font);
font-size: 20px;
font-style: normal;
@@ -53,41 +55,50 @@ const EditButton = styled.button`
box-shadow: 0px 3px 6px 0px #E5EAF8;
`
-interface Props {
- activeLink: string,
- allLength?: number,
- accessLength?: number,
- myLength?: number,
-}
+const Navbar: React.FC = observer(() => {
-const Navbar: React.FC = ({ activeLink, /*allLength, accessLength, myLength*/ }) => {
+ function openAll() {
+ navbarState.openAll();
+ }
+
+ function openAccess() {
+ navbarState.openAccess();
+ }
+
+ function openMy() {
+ navbarState.openMy();
+ }
function addRoom() {
- const currentUrl = window.location.href;
- if (currentUrl !== "http://localhost:5173/lobby/my") {
- window.location.href = '/lobby/my';
+ if (roomsFormState.state === '' && navbarState.state === 'my') {
roomsFormState.openCreateForm();
+ return 0;
}
- roomsFormState.openCreateForm();
+ if (roomsFormState.state === 'create') {
+ roomsFormState.closeCreateForm();
+ return 0;
+ }
}
function editRooms() {
- if (roomsState.state === '') {
- roomsState.openEditForm();
- return 0;
- }
- if (roomsState.state === 'edit') {
- roomsState.closeEditForm();
- return 0;
+ if (navbarState.state === 'my') {
+ if (roomsState.state === '') {
+ roomsState.openEditForm();
+ return 0;
+ }
+ if (roomsState.state === 'edit') {
+ roomsState.closeEditForm();
+ return 0;
+ }
}
}
return (
- Все классы({121})
- Доступные({5})
- Мои({2})
+ Все классы
+ Доступные
+ Мои
@@ -98,6 +109,6 @@ const Navbar: React.FC = ({ activeLink, /*allLength, accessLength, myLeng
)
-}
+})
export default Navbar;
\ No newline at end of file
diff --git a/src/widgets/layout/ProfileFormLayout.tsx b/src/widgets/layout/ProfileFormLayout.tsx
new file mode 100644
index 0000000..3086275
--- /dev/null
+++ b/src/widgets/layout/ProfileFormLayout.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import styled from "styled-components";
+
+const Container = styled.div`
+ position: relative;
+ width: 100%;
+ padding: 20px;
+ border-radius: 10px;
+ background: var(--white);
+ box-shadow: 0px 0px 4px 0px #e5eaf8;
+ font-family: var(--font);
+ color: #000;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+interface Props {
+ children?: React.ReactNode;
+}
+
+const ProfileFormLayout: React.FC = ({ children }) => {
+ return {children};
+};
+
+export default ProfileFormLayout;
diff --git a/src/widgets/layout/SettingClassLayout.tsx b/src/widgets/layout/SettingClassLayout.tsx
new file mode 100644
index 0000000..6b3cff0
--- /dev/null
+++ b/src/widgets/layout/SettingClassLayout.tsx
@@ -0,0 +1,52 @@
+import React from "react";
+import { styled } from "styled-components";
+import CheckBox from "../../shared/ui/checkBox/CheckBox";
+
+const Container = styled.div`
+ width: 100%;
+ display: flex;
+ padding-bottom: 20px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 20px;
+`;
+
+const Head = styled.div`
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ align-items: center;
+ gap: 100px;
+`;
+
+const Title = styled.div`
+ color: var(--black, #000);
+ font-family: var(--font);
+ font-size: 20px;
+ font-weight: 600;
+ line-height: normal;
+`;
+
+const Main = styled.div`
+ display: flex;
+ width: 100%;
+ flex-direction: column;
+ gap: 20px;
+`;
+
+interface Props {
+ title: string;
+ children?: React.ReactNode;
+}
+
+export const SettingClassLayout: React.FC = ({ title, children }) => {
+ return (
+
+
+ {title}
+
+
+ {children}
+
+ );
+};
diff --git a/src/widgets/layout/SettingsCallPopup/SettingsCallPopup.tsx b/src/widgets/layout/SettingsCallPopup/SettingsCallPopup.tsx
new file mode 100644
index 0000000..e25f357
--- /dev/null
+++ b/src/widgets/layout/SettingsCallPopup/SettingsCallPopup.tsx
@@ -0,0 +1,133 @@
+import React from "react";
+import styled from "styled-components";
+import settingsState from "../../../pages/CallPageCustomUI/store/settingsState";
+import { observer } from "mobx-react-lite";
+import FormButton from "../../../shared/ui/formButton/FormButton";
+import SettingsMy from "../../SettingsMy/SettingsMy";
+import SettingsClass from "../../SettingsClass/SettingsClass";
+
+const Container = styled.div`
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ min-width: 530px;
+ max-height: 100vh;
+ padding: 30px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 30px;
+ border-radius: 8px;
+ background: var(--white, #fff);
+ box-shadow: 0px 0px 2px 0px #c5ccd5;
+ z-index: 101;
+`;
+
+const Header = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ width: 100%;
+ padding-bottom: 20px;
+ border-bottom: 0.5px solid var(--grey-5, #d5dee8);
+`;
+
+const HeaderText = styled.div`
+ display: flex;
+ padding: 8px 16px;
+ align-items: flex-start;
+ gap: 10px;
+ color: var(--grey-1, #5f6a77);
+ font-family: var(--font);
+ font-size: 20px;
+ font-weight: 400;
+ line-height: normal;
+
+ &:hover {
+ cursor: pointer;
+ }
+`;
+
+const Settings = styled.form`
+ overflow: auto;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 20px;
+ padding-bottom: 5px;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+`;
+
+const Buttons = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 30px;
+`;
+
+const Back = styled.button`
+ color: var(--grey-1, #5f6a77);
+ font-family: var(--font);
+ font-size: 20px;
+ font-weight: 400;
+ line-height: normal;
+`;
+
+const styleSelected = {
+ color: "var(--blue, #175EF1)",
+ fontWeight: 600,
+};
+
+const SettingsCallPopup: React.FC = observer(() => {
+ function openMy() {
+ settingsState.selectMy();
+ }
+
+ function openClass() {
+ settingsState.selectClass();
+ }
+
+ function saveChanges() {
+ settingsState.closeSettings();
+ }
+
+ function backChanges() {
+ settingsState.closeSettings();
+ }
+
+ return (
+
+
+
+ Мои настройки
+
+
+ Настройки класса
+
+
+
+ {settingsState.selected === "My" && }
+ {settingsState.selected === "Class" && }
+
+ Сохранить
+ Отмена
+
+
+
+ );
+});
+
+export default SettingsCallPopup;