-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adding tabs for game details and torrent chat
- Loading branch information
1 parent
6d47213
commit 4d87090
Showing
29 changed files
with
1,106 additions
and
340 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { Box, CircularProgress } from '@mui/material' | ||
import { ButtonHTMLAttributes, forwardRef, ReactNode } from 'react' | ||
|
||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { | ||
children: ReactNode | ||
isLoading?: boolean | ||
icon?: ReactNode | ||
fullWidth?: boolean | ||
} | ||
|
||
const Button = forwardRef<HTMLButtonElement, ButtonProps>( | ||
( | ||
{ | ||
children, | ||
isLoading = false, | ||
icon, | ||
fullWidth = false, | ||
className = '', | ||
...rest | ||
}, | ||
ref, | ||
) => { | ||
return ( | ||
<button | ||
ref={ref} | ||
className={` | ||
flex items-center justify-center gap-2 px-6 py-3 rounded-md font-semibold text-white | ||
transition-colors duration-300 disabled:bg-opacity-50 disabled:cursor-not-allowed | ||
${fullWidth ? 'w-full' : 'w-auto'} | ||
${isLoading ? 'bg-theme-red-900' : 'bg-theme-red-900 hover:bg-red-700'} | ||
${className} | ||
`} | ||
disabled={isLoading} | ||
{...rest}> | ||
{isLoading ? ( | ||
<Box className="flex items-center justify-center"> | ||
<CircularProgress size={20} sx={{ color: 'white' }} /> | ||
</Box> | ||
) : ( | ||
<> | ||
{icon && <span className="flex items-center">{icon}</span>}{' '} | ||
{children} | ||
</> | ||
)} | ||
</button> | ||
) | ||
}, | ||
) | ||
|
||
Button.displayName = 'Button' | ||
|
||
export default Button |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './Button' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import { | ||
Box, | ||
Grid2, | ||
Rating as MuiRating, | ||
Stack, | ||
Switch, | ||
Typography, | ||
} from '@mui/material' | ||
import { useState } from 'react' | ||
import { RegisterOptions, SubmitHandler, useForm } from 'react-hook-form' | ||
import toast from 'react-hot-toast' | ||
|
||
import { Button, Input } from '@/components' | ||
import { GameDetails, ReviewStore } from '@/types' | ||
|
||
import { validations } from './validations' | ||
|
||
interface ReviewFormProps { | ||
game: GameDetails | ||
} | ||
|
||
function ReviewForm(props: ReviewFormProps) { | ||
const { game } = props | ||
const [played, setPlayed] = useState<boolean>(false) | ||
const [rating, setRating] = useState<number | null>(null) | ||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors }, | ||
} = useForm<ReviewStore>({ | ||
defaultValues: { comment: '' }, | ||
}) | ||
|
||
const getProps = ( | ||
key: keyof typeof validations, | ||
options?: RegisterOptions, | ||
) => ({ | ||
...register(key, { | ||
...validations[key], | ||
...options, | ||
} as RegisterOptions<ReviewStore>), | ||
error: !!errors[key], | ||
helperText: errors[key] && errors[key]?.message, | ||
}) | ||
|
||
const onSubmit: SubmitHandler<ReviewStore> = async (data) => { | ||
if (!rating) { | ||
toast.error('You need to rate this game to submit a review.') | ||
|
||
return | ||
} | ||
|
||
const payload: ReviewStore = { | ||
...data, | ||
played, | ||
userId: 1, | ||
rate: rating, | ||
gameId: game.id, | ||
} | ||
|
||
console.log(payload) | ||
} | ||
|
||
return ( | ||
<Stack component="form" onSubmit={handleSubmit(onSubmit)}> | ||
<Grid2 container spacing={1.5} mb={2}> | ||
<Box className="w-full flex flex-col gap-2"> | ||
<Typography | ||
variant="h6" | ||
className="dark:text-white text-gray-600"> | ||
Rate the Game | ||
</Typography> | ||
<MuiRating | ||
value={rating} | ||
precision={0.5} | ||
onChange={(_, v) => { | ||
if (v) { | ||
setRating(v) | ||
|
||
return | ||
} | ||
|
||
setRating(null) | ||
}} | ||
max={5} | ||
size="large" | ||
sx={{ | ||
color: '#ff4d4d', | ||
'& .MuiRating-iconFilled': { | ||
color: '#ff4d4d', | ||
}, | ||
'& .MuiRating-iconHover': { | ||
color: '#ff6666', | ||
}, | ||
}} | ||
/> | ||
{rating && ( | ||
<Typography className="block text-gray-400 font-semibold mt-1"> | ||
Rating: {rating} | ||
</Typography> | ||
)} | ||
</Box> | ||
<Box className="w-full flex flex-col gap-2"> | ||
<Typography | ||
variant="h6" | ||
className="dark:text-white text-gray-600"> | ||
Did you played this game? | ||
</Typography> | ||
<Switch | ||
value={played} | ||
checked={played} | ||
onChange={(_, v) => setPlayed(v)} | ||
sx={{ | ||
'& .MuiSwitch-switchBase': { | ||
color: '#ff4d4d', | ||
}, | ||
'& .MuiSwitch-switchBase.Mui-checked': { | ||
color: '#ff4d4d', | ||
}, | ||
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { | ||
backgroundColor: '#ff4d4d', | ||
}, | ||
'& .MuiSwitch-track': { | ||
backgroundColor: '#ccc', | ||
}, | ||
}} | ||
/> | ||
</Box> | ||
|
||
<Input | ||
area | ||
isFull | ||
label="Comment" | ||
placeholder="Write your comment here..." | ||
{...getProps('comment')} | ||
/> | ||
</Grid2> | ||
|
||
<Button>Submit</Button> | ||
</Stack> | ||
) | ||
} | ||
|
||
export default ReviewForm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './ReviewForm' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export const validations = { | ||
rate: { | ||
required: 'Please, write a number between 0 and 10.', | ||
min: { value: 0, message: 'The minimum value for a review is 0.' }, | ||
max: { value: 10, message: 'The maximum value for a review is 10.' }, | ||
}, | ||
played: { | ||
required: 'Please, tell me if you already played this game.', | ||
}, | ||
comment: { | ||
minLength: { | ||
value: 15, | ||
message: 'Your review must have at least 15 characters.', | ||
}, | ||
maxLength: { | ||
value: 2000, | ||
message: 'Your review can not have more than 2000 characters!', | ||
}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as ReviewForm } from './Review' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { | ||
ForwardedRef, | ||
forwardRef, | ||
InputHTMLAttributes, | ||
ReactNode, | ||
TextareaHTMLAttributes, | ||
useState, | ||
} from 'react' | ||
import { IoEyeOffOutline, IoEyeOutline } from 'react-icons/io5' | ||
|
||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> { | ||
error?: boolean | ||
type?: string | ||
placeholder?: string | ||
icon?: ReactNode | ||
isFull?: boolean | ||
helperText?: string | ||
area?: boolean | ||
customClass?: string | ||
label?: string | ||
rows?: number | ||
} | ||
|
||
function Input( | ||
{ | ||
icon, | ||
isFull = false, | ||
area = false, | ||
type, | ||
error, | ||
label, | ||
rows = 4, | ||
helperText, | ||
customClass, | ||
...rest | ||
}: InputProps, | ||
ref: ForwardedRef<HTMLInputElement>, | ||
) { | ||
const [passVisible, setPassVisible] = useState<boolean>(false) | ||
|
||
const toggleVisibility = () => { | ||
setPassVisible((prev) => !prev) | ||
} | ||
|
||
const baseClass = `px-4 py-2 rounded-md bg-transparent dark:text-white text-black placeholder-gray-400 focus:outline-none transition-colors duration-300 ${ | ||
isFull ? 'w-full' : 'w-auto' | ||
} ${error ? 'border-red-500' : 'border-zinc-600'} ${customClass}` | ||
|
||
return ( | ||
<div className={`relative ${isFull ? 'w-full' : 'inline-block'}`}> | ||
{label && ( | ||
<label className="block dark:text-white text-gray-600 font-semibold mb-1"> | ||
{label} | ||
</label> | ||
)} | ||
|
||
<div className="flex items-center border border-zinc-600 rounded-md"> | ||
{area ? ( | ||
<textarea | ||
rows={rows} | ||
ref={ref as React.Ref<HTMLTextAreaElement>} | ||
className={`${baseClass} resize-y flex-grow`} | ||
{...(rest as TextareaHTMLAttributes<HTMLTextAreaElement>)} | ||
/> | ||
) : ( | ||
<input | ||
ref={ref as React.Ref<HTMLInputElement>} | ||
type={type === 'password' && passVisible ? 'text' : type} | ||
className={`${baseClass} pr-12 flex-grow`} | ||
{...rest} | ||
/> | ||
)} | ||
|
||
{type === 'password' && ( | ||
<button | ||
type="button" | ||
onClick={toggleVisibility} | ||
className="flex items-center text-gray-500 hover:text-white focus:outline-none p-2"> | ||
{passVisible ? ( | ||
<IoEyeOutline size={20} /> | ||
) : ( | ||
<IoEyeOffOutline size={20} /> | ||
)} | ||
</button> | ||
)} | ||
|
||
{icon && ( | ||
<div className="flex items-center text-gray-500 p-2">{icon}</div> | ||
)} | ||
</div> | ||
|
||
{error && helperText && ( | ||
<span className="text-red-500 flex justify-start mt-1 text-sm"> | ||
{helperText} | ||
</span> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default forwardRef(Input) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './Input' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.