170 lines
4.1 KiB
TypeScript
170 lines
4.1 KiB
TypeScript
import {
|
||
Avatar,
|
||
Box,
|
||
Button,
|
||
Card,
|
||
CardBody,
|
||
CardFooter,
|
||
CardHeader,
|
||
Center,
|
||
HStack,
|
||
Heading,
|
||
Input,
|
||
Text,
|
||
VStack,
|
||
} from '@chakra-ui/react'
|
||
import { getFeatures } from '@brojs/cli'
|
||
import React, { memo, useCallback, useContext, useState } from 'react'
|
||
|
||
import { FormTest } from './from'
|
||
import { Stars } from '../stars'
|
||
import { stars as starsContext } from '../../__data__/context'
|
||
import { useUsers } from '../../hooks'
|
||
|
||
type User = Record<string, unknown> & {
|
||
id: string
|
||
name: string
|
||
avatar?: string
|
||
rated: number
|
||
friends?: User[]
|
||
}
|
||
|
||
const features = getFeatures('nav2')
|
||
|
||
export const Profile = ({
|
||
user,
|
||
isLink,
|
||
title,
|
||
}: {
|
||
user: User
|
||
isLink?: boolean
|
||
title?: string
|
||
}) => {
|
||
// const [rated, setRated] = useState(user.rated || 0)
|
||
const [editProfile, setEditProfile] = useState(false)
|
||
|
||
return (
|
||
<Box mt={3} borderWidth="1px" p={3} overflowX="hidden">
|
||
{!isLink && editProfile && <FormTest name={user.name} />}
|
||
{!editProfile && <Button onClick={() => setEditProfile(true)}>Редактировать</Button>}
|
||
<Heading as="h2">{title || 'Данные профиля'}</Heading>
|
||
<Box m={3}>
|
||
<Card width={'fit-content'} shadow="2xl">
|
||
<CardHeader>
|
||
<Center>
|
||
<Avatar size="xl" pt={1} src={user.avatar as string} />
|
||
</Center>
|
||
</CardHeader>
|
||
<CardBody>
|
||
<Text fontWeight="bold">Имя: {user.name.toUpperCase()}</Text>
|
||
</CardBody>
|
||
<CardFooter>
|
||
{features['stars'] && (
|
||
<Stars
|
||
count={Number(features['stars']?.value)}
|
||
userId={user.id}
|
||
// rated={rated}
|
||
// setRated={setRated}
|
||
/>
|
||
)}
|
||
</CardFooter>
|
||
</Card>
|
||
</Box>
|
||
{/* {!isLink &&
|
||
features['buttons'] &&
|
||
user.friends?.map((friend) => ( */}
|
||
<Counter
|
||
key={user.id}
|
||
// value={rated} setValue={setRated}
|
||
userId={user.id}
|
||
/>
|
||
{/* ))} */}
|
||
</Box>
|
||
)
|
||
}
|
||
|
||
const Form = memo<{ initialState: string; onSubmit(value: string): void }>(
|
||
({ initialState, onSubmit }) => {
|
||
const [message, setMessage] = useState(initialState)
|
||
|
||
const handleMessageChange = (event) => {
|
||
setMessage(event.target.value)
|
||
}
|
||
|
||
return (
|
||
<Box mt={3} mb={3}>
|
||
<Text fontWeight="bold">Написать сообщение:</Text>
|
||
|
||
<form
|
||
onSubmit={(event) => {
|
||
event.preventDefault()
|
||
onSubmit(message)
|
||
}}
|
||
>
|
||
<Box
|
||
bg="gray.100"
|
||
p={4}
|
||
borderRadius={3}
|
||
borderWidth={1}
|
||
mt={3}
|
||
mb={3}
|
||
rounded="md"
|
||
>
|
||
<label htmlFor="message">Сообщение:</label>
|
||
<Input
|
||
placeholder="Отпавим весточку?"
|
||
value={message}
|
||
onChange={handleMessageChange}
|
||
id="message"
|
||
/>
|
||
</Box>
|
||
<Button type="submit">Отправить</Button>
|
||
</form>
|
||
</Box>
|
||
)
|
||
},
|
||
)
|
||
|
||
Form.displayName = 'FormMemo'
|
||
|
||
const withStars =
|
||
(Component) =>
|
||
({ userId }) => {
|
||
const { stars, setStar } = useContext(starsContext)
|
||
|
||
const addStar = useCallback(
|
||
() => setStar(userId, stars[userId] + 1),
|
||
[userId, setStar],
|
||
)
|
||
const subStar = useCallback(
|
||
() => setStar(userId, stars[userId] - 1),
|
||
[userId, setStar],
|
||
)
|
||
|
||
return (
|
||
<Component
|
||
userId={userId}
|
||
stars={stars[userId]}
|
||
addStar={addStar}
|
||
subStar={subStar}
|
||
/>
|
||
)
|
||
}
|
||
|
||
const Counter = ({ stars, addStar, subStar, userId }: { userId: 'some-user-id' | '2'}) => {
|
||
const { rate, setUserRate } = useUsers((state) => state[userId].rated)
|
||
|
||
return (
|
||
<Center>
|
||
<VStack>
|
||
<Heading>{rate}</Heading>
|
||
|
||
<Button onClick={() => setUserRate(userId, rate + 1)}>+</Button>
|
||
<Button onClick={() => setUserRate(userId, rate - 1)}>-</Button>
|
||
</VStack>
|
||
</Center>
|
||
)
|
||
}
|
||
|
||
const CounterWithStars = withStars(Counter)
|