Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9522261b89 | |||
| 4b5d0d20df | |||
| 20627e0c98 |
@@ -36,7 +36,7 @@ const Cell = ({ cell, callbacks }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex ref={setNodeRef} sx={theme => {
|
<Flex ref={setNodeRef} w='10vh' sx={theme => {
|
||||||
let color = theme.colors.lime;
|
let color = theme.colors.lime;
|
||||||
return { backgroundColor: squareColor === 'b' ? '#769854' : '#e8edcd', aspectRatio: '1/1' }
|
return { backgroundColor: squareColor === 'b' ? '#769854' : '#e8edcd', aspectRatio: '1/1' }
|
||||||
}} onClick={handleClick} bg={squareColor === 'w' ? "white" : "gray"} >
|
}} onClick={handleClick} bg={squareColor === 'w' ? "white" : "gray"} >
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ const GameHistory = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '100%', userSelect: 'none' }}>
|
<div style={{ width: '600px', userSelect: 'none' }}>
|
||||||
<ScrollArea h={400} scrollbarSize={6} >
|
<ScrollArea h={'640px'} scrollbarSize={6} >
|
||||||
<Flex direction='column' align='start' w='100%'>
|
<Flex direction='column' align='start' w='100%'>
|
||||||
{gameHistoryJSX}
|
{gameHistoryJSX}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -1,95 +1,129 @@
|
|||||||
import React, { useContext, useState } from 'react'
|
import React, { useContext, useState } from "react";
|
||||||
|
|
||||||
import { Outlet } from 'react-router-dom'
|
import { Outlet } from "react-router-dom";
|
||||||
import { AppShell, Burger, Container, Header, MediaQuery, Navbar, Paper, Text, createStyles, useMantineTheme } from '@mantine/core'
|
import {
|
||||||
|
AppShell,
|
||||||
|
Burger,
|
||||||
|
Container,
|
||||||
|
Header,
|
||||||
|
MediaQuery,
|
||||||
|
Navbar,
|
||||||
|
Paper,
|
||||||
|
Text,
|
||||||
|
createStyles,
|
||||||
|
useMantineTheme,
|
||||||
|
} from "@mantine/core";
|
||||||
|
|
||||||
import UserDataContextProvider, { UserDataContext } from '../context/user-data-context';
|
import UserDataContextProvider, {
|
||||||
import MainLoader from '../components/MainLoader';
|
UserDataContext,
|
||||||
import NavbarLinks from '../components/NavbarLinks';
|
} from "../context/user-data-context";
|
||||||
import Logout from '../components/Logout';
|
import MainLoader from "../components/MainLoader";
|
||||||
|
import NavbarLinks from "../components/NavbarLinks";
|
||||||
|
import Logout from "../components/Logout";
|
||||||
|
|
||||||
const useStyles = createStyles(() => ({
|
const useStyles = createStyles(() => ({
|
||||||
body: {
|
body: {
|
||||||
width: '100%',
|
width: "100%",
|
||||||
height: '100%'
|
height: "100%",
|
||||||
|
},
|
||||||
},
|
root: {
|
||||||
root: {
|
width: "100%",
|
||||||
width: '100%',
|
height: "100vh",
|
||||||
height: '100vh'
|
},
|
||||||
|
main: {
|
||||||
},
|
width: "100%",
|
||||||
main: {
|
height: "100vh",
|
||||||
width: '100%',
|
},
|
||||||
height: '100vh'
|
}));
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
const MainLayout = () => {
|
const MainLayout = () => {
|
||||||
const { classes } = useStyles();
|
const { classes } = useStyles();
|
||||||
const theme = useMantineTheme();
|
const theme = useMantineTheme();
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
const { isLoggedIn, errorMessage } = useContext(UserDataContext);
|
const { isLoggedIn, errorMessage } = useContext(UserDataContext);
|
||||||
|
|
||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
return <MainLoader errorMessage={errorMessage} />
|
return <MainLoader errorMessage={errorMessage} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserDataContextProvider>
|
<UserDataContextProvider>
|
||||||
<Paper>
|
<Paper>
|
||||||
<AppShell classNames={{
|
<AppShell
|
||||||
body: classes.body,
|
classNames={{
|
||||||
root: classes.root,
|
body: classes.body,
|
||||||
main: classes.main
|
root: classes.root,
|
||||||
}}
|
main: classes.main,
|
||||||
styles={{
|
}}
|
||||||
main: {
|
styles={{
|
||||||
background: theme.colorScheme === 'dark' ? '#302e2a' : theme.colors.gray[0]
|
main: {
|
||||||
},
|
background:
|
||||||
body: {
|
theme.colorScheme === "dark" ? "#302e2a" : theme.colors.gray[0],
|
||||||
textAlign: 'center'
|
},
|
||||||
}
|
body: {
|
||||||
}}
|
textAlign: "center",
|
||||||
layout='alt'
|
},
|
||||||
navbar={
|
}}
|
||||||
<Navbar py="md" px="0" hiddenBreakpoint="md" sx={{ backgroundColor: '#262523' }} hidden={!opened} width={{ md: 150 }}>
|
layout="alt"
|
||||||
<Navbar.Section>
|
navbar={
|
||||||
<Text size={30} weight={700}>Chess</Text>
|
<Navbar
|
||||||
</Navbar.Section>
|
py="md"
|
||||||
<Navbar.Section grow mt="md">
|
px="0"
|
||||||
<NavbarLinks />
|
hiddenBreakpoint="md"
|
||||||
</Navbar.Section>
|
sx={{ backgroundColor: "#262523" }}
|
||||||
<Navbar.Section >
|
hidden={!opened}
|
||||||
<Logout />
|
width={{ md: 150 }}
|
||||||
</Navbar.Section>
|
>
|
||||||
</Navbar>
|
<Navbar.Section>
|
||||||
}
|
<Text size={30} weight={700}>
|
||||||
header={
|
Chess
|
||||||
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
|
</Text>
|
||||||
<Header zIndex={1000} p="md">
|
</Navbar.Section>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', height: '100%' }}>
|
<Navbar.Section grow mt="md">
|
||||||
<Burger
|
<NavbarLinks />
|
||||||
opened={opened}
|
</Navbar.Section>
|
||||||
onClick={() => setOpened((o) => !o)}
|
<Navbar.Section>
|
||||||
size="sm"
|
<Logout />
|
||||||
color={theme.colors.gray[6]}
|
</Navbar.Section>
|
||||||
mr="xl"
|
</Navbar>
|
||||||
/>
|
}
|
||||||
|
header={
|
||||||
<Text>Application header</Text>
|
<MediaQuery largerThan="sm" styles={{ display: "none" }}>
|
||||||
</div>
|
<Header zIndex={1000} p="md">
|
||||||
</Header>
|
<div
|
||||||
</MediaQuery>
|
style={{
|
||||||
}
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Container size="100%" px={{ 'md': '10px', 'lg': '30px' }} >
|
<Burger
|
||||||
<Outlet />
|
opened={opened}
|
||||||
</Container>
|
onClick={() => setOpened((o) => !o)}
|
||||||
</AppShell>
|
size="sm"
|
||||||
</Paper>
|
color={theme.colors.gray[6]}
|
||||||
</UserDataContextProvider>
|
mr="xl"
|
||||||
);
|
/>
|
||||||
}
|
|
||||||
|
|
||||||
export default MainLayout
|
<Text>Application header</Text>
|
||||||
|
</div>
|
||||||
|
</Header>
|
||||||
|
</MediaQuery>
|
||||||
|
}
|
||||||
|
padding
|
||||||
|
>
|
||||||
|
<Container
|
||||||
|
size="100%"
|
||||||
|
style={{ height: "100vh" }}
|
||||||
|
pl={{ md: 150 }}
|
||||||
|
pr={{ md: 0 }}
|
||||||
|
>
|
||||||
|
<Outlet />
|
||||||
|
</Container>
|
||||||
|
</AppShell>
|
||||||
|
</Paper>
|
||||||
|
</UserDataContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MainLayout;
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ const ChessBoard = ({ callbacks }) => {
|
|||||||
if (myColor === 'w') {
|
if (myColor === 'w') {
|
||||||
return (
|
return (
|
||||||
<DndContext onDragEnd={dragEndCallback}>
|
<DndContext onDragEnd={dragEndCallback}>
|
||||||
<Flex className={classes.chessboard} sx={{ userSelect: 'none' }}>
|
<Flex h='80vh' sx={{ userSelect: 'none' }}>
|
||||||
<div>
|
<div>
|
||||||
{chessBoard.map((row, rowIndex) => {
|
{chessBoard.map((row, rowIndex) => {
|
||||||
return (
|
return (
|
||||||
<Flex className={classes.boardrow} key={rowIndex * 2}>
|
<Flex key={rowIndex * 2}>
|
||||||
{row.map(cell => <Cell callbacks={{ pieceClickCallback: callbacks.pieceClickCallback }} key={cell.square} cell={cell} />)}
|
{row.map(cell => <Cell callbacks={{ pieceClickCallback: callbacks.pieceClickCallback }} key={cell.square} cell={cell} />)}
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
@@ -83,11 +83,11 @@ const ChessBoard = ({ callbacks }) => {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<DndContext onDragEnd={dragEndCallback}>
|
<DndContext onDragEnd={dragEndCallback}>
|
||||||
<Flex className={classes.chessboard}>
|
<Flex h='80vh' sx={{userSelect:'none'}}>
|
||||||
<div>
|
<div>
|
||||||
{chessBoard.map((row, rowIndex) => {
|
{chessBoard.map((row, rowIndex) => {
|
||||||
return (
|
return (
|
||||||
<Flex className={classes.boardrow} key={rowIndex * 2}>
|
<Flex key={rowIndex * 2}>
|
||||||
{row.map(cell => <Cell callbacks={{ pieceClickCallback: callbacks.pieceClickCallback }} key={cell.square} cell={cell} />).reverse()}
|
{row.map(cell => <Cell callbacks={{ pieceClickCallback: callbacks.pieceClickCallback }} key={cell.square} cell={cell} />).reverse()}
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ const ChallengeFriend = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
maw={450} sx={{
|
sx={{
|
||||||
width: '100%',
|
width: '600px',
|
||||||
height: '600px',
|
height: '80%',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
backgroundColor: '#262523'
|
backgroundColor: '#262523'
|
||||||
}}
|
}}
|
||||||
|
px='20px'
|
||||||
>
|
>
|
||||||
<Form action={`/play/friend/${friend_username}`} method='POST'>
|
<Form action={`/play/friend/${friend_username}`} method='POST'>
|
||||||
<Flex align="center" direction="column" justify="center" gap="xs" my="lg">
|
<Flex align="center" direction="column" justify="center" gap="xs" my="lg">
|
||||||
|
|||||||
@@ -70,15 +70,17 @@ const ChessGameComputer = () => {
|
|||||||
<Button mx='md' color='lime' onClick={modalFunctions.close}>OK</Button>
|
<Button mx='md' color='lime' onClick={modalFunctions.close}>OK</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Flex gap="xl" miw={360} justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
<Flex gap="xl" miw={360} justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
||||||
<Flex gap="xs" justify='center' align='start' wrap='nowrap' direction='column' >
|
<Flex gap="xs" justify='center' h='100vh' align='start' wrap='nowrap' direction='column' >
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<NavLink
|
<NavLink
|
||||||
style={{ width: "500px" }}
|
style={{ width: "500px" }}
|
||||||
p="2px"
|
p="2px"
|
||||||
// label={isWaiting ? "Waiting for opponent..." : opponent}
|
// label={isWaiting ? "Waiting for opponent..." : opponent}
|
||||||
icon={<Avatar radius="3px" >
|
// icon={<Avatar radius="3px" style={{ minWidth: "4.374rem" }} >
|
||||||
Computer
|
// Computer
|
||||||
</Avatar>}
|
// </Avatar>}
|
||||||
|
icon = { <img src="https://www.chess.com/bundles/web/images/color-icons/computer.2318c3b4.svg" alt="computer-icon" style={{height:"38px" , width:"38px" ,borderRadius:"3px"}} /> }
|
||||||
|
|
||||||
description={"description"}
|
description={"description"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,9 +111,9 @@ const ChessGameComputer = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
<MediaQuery smallerThan="lg" styles={{ display: 'none' }}>
|
<MediaQuery smallerThan="lg" styles={{ display: 'none' }}>
|
||||||
<Flex maw={450} sx={{
|
<Flex maw={600} sx={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '840px',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
borderRadius: '10px',
|
borderRadius: '10px',
|
||||||
backgroundColor: '#272623'
|
backgroundColor: '#272623'
|
||||||
|
|||||||
@@ -109,11 +109,10 @@ const ChessGameMultiplayer = () => {
|
|||||||
<Button color='lime' onClick={exitGame}>Go back</Button>
|
<Button color='lime' onClick={exitGame}>Go back</Button>
|
||||||
<Button mx='md' color='lime' onClick={modalFunctions.close}>OK</Button>
|
<Button mx='md' color='lime' onClick={modalFunctions.close}>OK</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Flex gap="xl" miw={360} justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
<Flex gap="xl" justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
||||||
<Flex gap="xs" justify='center' align='start' wrap='nowrap' direction='column' >
|
<Flex gap="xs" justify='center' h='100vh' align='start' wrap='nowrap' direction='column' >
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<div style={{ width:"100%", height:'6vh', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<NavLink
|
<NavLink
|
||||||
style={{ width: "500px" }}
|
|
||||||
p="2px"
|
p="2px"
|
||||||
label={isWaiting ? "Waiting for opponent..." : opponent}
|
label={isWaiting ? "Waiting for opponent..." : opponent}
|
||||||
icon={<Avatar radius="3px" >
|
icon={<Avatar radius="3px" >
|
||||||
@@ -125,19 +124,19 @@ const ChessGameMultiplayer = () => {
|
|||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
// TODO: handle isWaiting state
|
// TODO: handle isWaiting state
|
||||||
false ?
|
// false ?
|
||||||
<>
|
// <>
|
||||||
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
|
// <MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
|
||||||
<Image width={600} miw={480} src="/src/assets/images/chess_board.png" />
|
// <Image width={600} miw={480} src="/src/assets/images/chess_board.png" />
|
||||||
</MediaQuery>
|
// </MediaQuery>
|
||||||
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
|
// <MediaQuery largerThan="sm" styles={{ display: 'none' }}>
|
||||||
<Image width="100%" maw={540} src="/src/assets/images/chess_board.png" />
|
// <Image width="100%" maw={540} src="/src/assets/images/chess_board.png" />
|
||||||
</MediaQuery>
|
// </MediaQuery>
|
||||||
</>
|
// </>
|
||||||
:
|
// :
|
||||||
<ChessBoard callbacks={{ pieceDropCallback, pieceClickCallback }} />
|
<ChessBoard callbacks={{ pieceDropCallback, pieceClickCallback }} />
|
||||||
}
|
}
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<div style={{ width:"100%", height:'6vh', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<NavLink
|
<NavLink
|
||||||
style={{ width: "500px" }}
|
style={{ width: "500px" }}
|
||||||
p="2px"
|
p="2px"
|
||||||
@@ -151,9 +150,9 @@ const ChessGameMultiplayer = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
<MediaQuery smallerThan="lg" styles={{ display: 'none' }}>
|
<MediaQuery smallerThan="lg" styles={{ display: 'none' }}>
|
||||||
<Flex maw={450} sx={{
|
<Flex maw={600} sx={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '840px',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
borderRadius: '10px',
|
borderRadius: '10px',
|
||||||
backgroundColor: '#272623'
|
backgroundColor: '#272623'
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ const Computer = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
maw={450}
|
maw={600}
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "600px",
|
height: "75vh",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
backgroundColor: "#262523",
|
backgroundColor: "#262523",
|
||||||
}}
|
}}
|
||||||
|
p={'30px'}
|
||||||
>
|
>
|
||||||
<Flex align="center" justify="center" gap="xs" my="lg">
|
<Flex align="center" justify="center" gap="xs" my="lg">
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ const Layout = () => {
|
|||||||
const user = getUserData();
|
const user = getUserData();
|
||||||
let username = user.username;
|
let username = user.username;
|
||||||
return (
|
return (
|
||||||
<Flex gap="xl" miw={360} justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
<Flex h='100vh' justify='center' align='center' wrap='nowrap' mt={{ base: '50px', sm: '0px' }} direction={{ base: 'column', lg: 'row' }}>
|
||||||
<Flex gap="xs" justify='center' align='start' wrap='nowrap' direction='column' >
|
<Flex gap="xs" h={'95vh'} justify='center' align='start' wrap='nowrap' direction='column' >
|
||||||
<NavLink
|
<NavLink
|
||||||
p="2px"
|
p="2px"
|
||||||
label={"opponent"}
|
label={"opponent"}
|
||||||
@@ -18,7 +18,7 @@ const Layout = () => {
|
|||||||
description={"description"}
|
description={"description"}
|
||||||
/>
|
/>
|
||||||
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
|
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
|
||||||
<img draggable={false} width={600} miw={480} src="/src/assets/images/chess_board.png" />
|
<img draggable={false} height={'100%'} style={{aspectRatio:'1'}} miw={480} src="/src/assets/images/chess_board.png" />
|
||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
|
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
|
||||||
<img draggable={false} width="100%" maw={540} src="/src/assets/images/chess_board.png" />
|
<img draggable={false} width="100%" maw={540} src="/src/assets/images/chess_board.png" />
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import { Card, Flex, Image, NavLink, Title } from '@mantine/core'
|
|||||||
|
|
||||||
const Play = () => {
|
const Play = () => {
|
||||||
return (
|
return (
|
||||||
<Card maw={450} sx={{
|
<Card sx={{
|
||||||
width: '100%',
|
width: '540px',
|
||||||
height: '600px',
|
height: '75%',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
backgroundColor: '#262523'
|
backgroundColor: '#262523'
|
||||||
}}>
|
}}>
|
||||||
<Flex gap="5px" px="20px" justify='center' align='center' wrap='nowrap' direction='column'>
|
<Flex gap="15px" px="20px" justify='center' align='center' wrap='nowrap' direction='column'>
|
||||||
<Title order={2} >Play Chess</Title>
|
<Title order={2} >Play Chess</Title>
|
||||||
<Image my="md" withPlaceholder width={200} height={120} src={null} />
|
<Image my="md" withPlaceholder width={200} height={120} src={null} />
|
||||||
{
|
{
|
||||||
@@ -32,6 +32,7 @@ const CardItem = ({ label, description, src, to }) => {
|
|||||||
icon={<Image src={src} width={50} />}
|
icon={<Image src={src} width={50} />}
|
||||||
description={description}
|
description={description}
|
||||||
sx={{ backgroundColor: '#1f1f1a', borderRadius: '5px' }}
|
sx={{ backgroundColor: '#1f1f1a', borderRadius: '5px' }}
|
||||||
|
p='20px'
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ const PlayFriend = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Card
|
<Card
|
||||||
maw={450} sx={{
|
sx={{
|
||||||
width: '100%',
|
width: '600px',
|
||||||
height: '600px',
|
height: '90%',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
backgroundColor: '#262523'
|
backgroundColor: '#262523'
|
||||||
}}
|
}}
|
||||||
|
px='30px'
|
||||||
>
|
>
|
||||||
<Flex align="center" justify="center" gap="xs" my="lg">
|
<Flex align="center" justify="center" gap="xs" my="lg">
|
||||||
<Image width="30px" src="https://www.chess.com/bundles/web/images/color-icons/handshake.fb30f50b.svg" />
|
<Image width="30px" src="https://www.chess.com/bundles/web/images/color-icons/handshake.fb30f50b.svg" />
|
||||||
|
|||||||
Reference in New Issue
Block a user