Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…k-class-frontend into develop
  • Loading branch information
Emil307 committed Aug 17, 2023
2 parents 88a5e6a + 92d719d commit 1404d6e
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 27 deletions.
37 changes: 15 additions & 22 deletions src/entities/user/ui/UserCard.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import { useAuth0 } from "@auth0/auth0-react";
import React, { useState } from "react";
import React from "react";
import { styled } from "styled-components";
import avatar from "../../../../public/icons/avatar.svg";
import CardButton from "../../../shared/ui/cardButton/CardButton";

const Container = styled.div`
font-family: var(--font);
color: #000;
display: flex;
width: 100%;
padding: 20px;
justify-content: space-between;
align-items: center;
border-radius: 10px;
background: var(--white, #fff);
box-shadow: 0px 0px 4px 0px #e5eaf8;
`;
import ProfileFormLayout from "../../../widgets/layout/ProfileFormLayout";
import profileFormState from "../../../pages/Profile/store/profileFormState";
import { observer } from "mobx-react-lite";

const User = styled.div`
height: 100%;
Expand Down Expand Up @@ -69,16 +59,19 @@ const AccessText = styled.a`
}
`;

const UserCard: React.FC = () => {
const [isEmailConfirmed, setIsEmailConfirmed] = useState(false);
const UserCard: React.FC = observer(() => {
const { user } = useAuth0();

const sendAccess = () => {
setIsEmailConfirmed(true);
profileFormState.confirmEmail();
};

const openForm = () => {
profileFormState.openEditForm();
};

return (
<Container>
<ProfileFormLayout>
<User>
<Avatar src={avatar && user?.picture} />
<Info>
Expand All @@ -87,7 +80,7 @@ const UserCard: React.FC = () => {
<EmailText>{user?.email}</EmailText>
{!user?.email_verified ? (
<AccessEmail>
{isEmailConfirmed ? (
{profileFormState.isEmailConfirmed ? (
<div style={{ color: "var(--green, #5bc259)" }}>
На вашу почту выслано письмо с подтверждением
</div>
Expand All @@ -103,9 +96,9 @@ const UserCard: React.FC = () => {
</Email>
</Info>
</User>
<CardButton>Изменить</CardButton>
</Container>
<CardButton onClick={openForm}>Изменить</CardButton>
</ProfileFormLayout>
);
};
});

export default UserCard;
1 change: 1 addition & 0 deletions src/features/editUser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EditUserForm } from "./ui/EditUserForm";
177 changes: 177 additions & 0 deletions src/features/editUser/ui/EditUserForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import React, { useState } from "react";
import styled from "styled-components";
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;
}
`;

const User = styled.div`
height: 100%;
display: flex;
align-items: center;
gap: 20px;
`;

const Avatar = styled.div`
width: 86px;
height: 86px;
border-radius: 10px;
border: 2px dashed #175ef1;
position: relative;
`;

const InputAvatar = styled.input`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: transparent;
&:hover {
cursor: pointer;
}
&::file-selector-button {
display: none;
}
`;

const Info = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
`;

const Name = styled.input`
width: 100%;
font-size: 22px;
font-weight: 500;
`;

const Email = styled.div`
display: flex;
align-items: center;
gap: 12px;
`;

const EmailText = styled.div`
font-size: 20px;
font-weight: 300;
line-height: normal;
`;

const AccessEmail = styled.a`
font-size: 20px;
font-weight: 300;
line-height: normal;
`;

const AccessText = styled.a`
color: var(--red, #f95a39);
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;

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<HTMLInputElement>) => {
if (event.target.files && event.target.files[0]) {
setAvatar(URL.createObjectURL(event.target.files[0]));
}
};

return (
<ProfileFormLayout>
<Form
action=""
autoComplete="off"
method="post"
encType="multipart/form-data"
onSubmit={saveChanges}
>
<User>
<Avatar>
<img
src={avatar}
alt=""
style={{ width: "100%", height: "100%", borderRadius: "7px" }}
/>
<InputAvatar type="file" title=" " onChange={onImageChange} />
</Avatar>
<Info>
<Name
type="text"
value={name}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setName(e.target.value)
}
autoFocus
/>
<Email>
<EmailText>{user?.email}</EmailText>
{!user?.email_verified ? (
<AccessEmail>
{profileFormState.isEmailConfirmed ? (
<div style={{ color: "var(--green, #5bc259)" }}>
На вашу почту выслано письмо с подтверждением
</div>
) : (
<AccessText onClick={sendAccess}>
Подтвердите почту
</AccessText>
)}
</AccessEmail>
) : (
""
)}
</Email>
</Info>
</User>
<FormButton>Сохранить</FormButton>
</Form>
</ProfileFormLayout>
);
});
9 changes: 6 additions & 3 deletions src/pages/Profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ 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``;

Expand All @@ -18,17 +21,17 @@ const ProfileCard = styled.div`
margin: 0 121px 73px 123px;
`;

const Profile: React.FC = () => {
const Profile: React.FC = observer(() => {
return (
<Container>
<Header />
<Title>Мой профиль</Title>
<ProfileCard>
<UserCard />
{profileFormState.state ? <EditUserForm /> : <UserCard />}
</ProfileCard>
<Statistics />
</Container>
);
};
});

export default Profile;
23 changes: 23 additions & 0 deletions src/pages/Profile/store/profileFormState.tsx
Original file line number Diff line number Diff line change
@@ -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();
5 changes: 3 additions & 2 deletions src/shared/ui/cardButton/CardButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ const Button = styled.button`

interface Props {
children?: string;
onClick?: () => void;
}

const CardButton: React.FC<Props> = ({ children }) => {
return <Button>{children}</Button>;
const CardButton: React.FC<Props> = ({ children, onClick }) => {
return <Button onClick={onClick}>{children}</Button>;
};

export default CardButton;
26 changes: 26 additions & 0 deletions src/widgets/layout/ProfileFormLayout.tsx
Original file line number Diff line number Diff line change
@@ -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<Props> = ({ children }) => {
return <Container>{children}</Container>;
};

export default ProfileFormLayout;

0 comments on commit 1404d6e

Please sign in to comment.