profile card

This commit is contained in:
Primakov Alexandr Alexandrovich 2024-10-29 16:39:32 +03:00
parent 2971f2b90d
commit 65e20202fb
6 changed files with 128 additions and 2 deletions

37
package-lock.json generated
View File

@ -13,6 +13,8 @@
"@chakra-ui/react": "^2.10.3", "@chakra-ui/react": "^2.10.3",
"@eslint/js": "^9.11.0", "@eslint/js": "^9.11.0",
"@stylistic/eslint-plugin": "^2.8.0", "@stylistic/eslint-plugin": "^2.8.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"eslint": "^9.11.0", "eslint": "^9.11.0",
"eslint-plugin-react": "^7.36.1", "eslint-plugin-react": "^7.36.1",
"express": "^4.19.2", "express": "^4.19.2",
@ -20,6 +22,7 @@
"lottie-react": "^2.4.0", "lottie-react": "^2.4.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-router-dom": "^6.23.1", "react-router-dom": "^6.23.1",
"typescript-eslint": "^8.6.0" "typescript-eslint": "^8.6.0"
} }
@ -2580,6 +2583,31 @@
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/prop-types": {
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz",
"integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==",
"license": "MIT",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.6.0", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz",
@ -8462,6 +8490,15 @@
} }
} }
}, },
"node_modules/react-icons": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz",
"integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",

View File

@ -20,6 +20,8 @@
"@chakra-ui/react": "^2.10.3", "@chakra-ui/react": "^2.10.3",
"@eslint/js": "^9.11.0", "@eslint/js": "^9.11.0",
"@stylistic/eslint-plugin": "^2.8.0", "@stylistic/eslint-plugin": "^2.8.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"eslint": "^9.11.0", "eslint": "^9.11.0",
"eslint-plugin-react": "^7.36.1", "eslint-plugin-react": "^7.36.1",
"express": "^4.19.2", "express": "^4.19.2",
@ -27,6 +29,7 @@
"lottie-react": "^2.4.0", "lottie-react": "^2.4.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-router-dom": "^6.23.1", "react-router-dom": "^6.23.1",
"typescript-eslint": "^8.6.0" "typescript-eslint": "^8.6.0"
} }

1
src/components/index.ts Normal file
View File

@ -0,0 +1 @@
export { Profile } from './profile'

View File

@ -0,0 +1 @@
export { Profile } from './profile'

View File

@ -0,0 +1,66 @@
import {
Avatar,
Box,
Card,
CardBody,
CardFooter,
CardHeader,
HStack,
Heading,
Icon,
Text,
} from '@chakra-ui/react'
import { FaRegStar, FaStar } from 'react-icons/fa6'
import React, { useState } from 'react'
type User = Record<string, unknown> & {
name: string
avatar?: string
rated: number
}
export const Profile = ({ user }: { user: User }) => {
const [rated, setRated] = useState(user.rated || 0)
return (
<Box mt={3} borderWidth="1px" p={3} overflowX="hidden">
<Heading as="h2">Данные профиля</Heading>
<Box m={3}>
<Card width={'fit-content'} shadow="2xl">
<CardHeader>
<Avatar size="xl" pt={1} src={user.avatar as string} />
</CardHeader>
<CardBody>
<Text fontWeight="bold">Имя: {user.name.toUpperCase()}</Text>
</CardBody>
<CardFooter>
<HStack>
{Array.from({ length: 5 }).map((_, index) =>
index + 1 > rated ? (
<Icon
key={index}
color="orange.400"
cursor="pointer"
onClick={() => setRated(index + 1)}
>
<FaRegStar />
</Icon>
) : (
<Icon
key={index}
color="orange.400"
cursor="pointer"
onClick={() => setRated(index + 1)}
>
<FaStar />
</Icon>
),
)}
</HStack>
</CardFooter>
</Card>
</Box>
<pre>{JSON.stringify(user, null, 4)}</pre>
</Box>
)
}

View File

@ -1,13 +1,31 @@
import { Container } from '@chakra-ui/react' import { Container, Heading } from '@chakra-ui/react'
import React from 'react' import React from 'react'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import { Profile } from '../components'
const users = {
'some-user-id': {
name: 'alexandr',
secondName: null,
email: null,
rated: 3,
avatar: 'https://www.gravatar.com/avatar/6529e885535ef67a3fad810ad71167c2c03f79480936e9b3a714731753cbb47e?d=robohash'
}
}
export const ByPage = () => { export const ByPage = () => {
const params = useParams() const params = useParams()
const user = users[params.userId]
return ( return (
<Container maxW="container.xl"> <Container maxW="container.xl">
<pre>{JSON.stringify(params, null, 4)}</pre> {user ? (
<Profile user={user} />
) : (
<Heading as="h2">Пользователь не найден</Heading>
)}
</Container> </Container>
) )
} }