fix: improve overall rendering v2 (#15)

Follow-up of #10

Co-authored-by: Walidoux <ma.walidkorchi@icloud.com>
This commit is contained in:
Divlo 2022-03-16 11:25:44 +01:00 committed by GitHub
parent 780788d682
commit 8f74263daa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 133 additions and 101 deletions

View File

@ -1,5 +1,7 @@
import Image from 'next/image' import Image from 'next/image'
import { useState } from 'react' import { useState } from 'react'
import useTranslation from 'next-translate/useTranslation'
import classNames from 'classnames'
import { Loader } from '../../design/Loader' import { Loader } from '../../design/Loader'
@ -9,22 +11,32 @@ export interface ConfirmGuildJoinProps {
handleNo: () => void | Promise<void> handleNo: () => void | Promise<void>
} }
export const ConfirmGuildJoin: React.FC<ConfirmGuildJoinProps> = (props) => { export const ConfirmGuildJoin: React.FC<ConfirmGuildJoinProps> = ({
const { className, handleYes, handleNo } = props ...props
}) => {
const { t } = useTranslation()
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const handleYesLoading = async (): Promise<void> => { const handleYesLoading = async (): Promise<void> => {
setIsLoading((isLoading) => !isLoading) setIsLoading((isLoading) => !isLoading)
await handleYes() await props.handleYes()
} }
return ( return (
<div className={className}> <div className={props.className}>
{isLoading ? ( <Loader
<Loader /> className={classNames('absolute scale-0 transition', {
) : ( 'scale-100': isLoading
<> })}
/>
<div
className={classNames(
'visible flex flex-col items-center opacity-100 transition-all',
{
'invisible opacity-0': isLoading
}
)}
>
<Image <Image
src='/images/svg/design/join-guild.svg' src='/images/svg/design/join-guild.svg'
alt='Join Guild Illustration' alt='Join Guild Illustration'
@ -32,24 +44,25 @@ export const ConfirmGuildJoin: React.FC<ConfirmGuildJoinProps> = (props) => {
width={150} width={150}
/> />
<div className='mt-8 flex flex-col'> <div className='mt-8 flex flex-col'>
<h1 className='mb-6 text-center text-xl'>Rejoindre la guild ?</h1> <h1 className='mb-6 text-center text-xl'>
{t('application:join-the-guild')} ?
</h1>
<div className='flex gap-7'> <div className='flex gap-7'>
<button <button
className='rounded-3xl bg-success px-8 py-2 transition hover:opacity-50' className='rounded-3xl bg-success px-8 py-2 text-white transition hover:brightness-125 dark:text-black hover:dark:brightness-75'
onClick={handleYesLoading} onClick={handleYesLoading}
> >
Oui {t('common:yes')}
</button> </button>
<button <button
className='rounded-3xl bg-error px-8 py-2 transition hover:opacity-50' className='rounded-3xl bg-error px-8 py-2 text-white transition hover:brightness-125 dark:text-black hover:dark:brightness-75'
onClick={handleNo} onClick={props.handleNo}
> >
Non {t('common:no')}
</button> </button>
</div> </div>
</div> </div>
</> </div>
)}
</div> </div>
) )
} }

View File

@ -53,7 +53,7 @@ export const GuildPublic: React.FC<GuildPublicProps> = (props) => {
} }
return ( return (
<div className='relative overflow-hidden rounded border border-gray-500 shadow-lg transition duration-200 ease-in-out hover:-translate-y-2 hover:shadow-none dark:border-gray-700'> <div className='relative h-80 overflow-hidden rounded border border-gray-500 shadow-lg transition duration-200 ease-in-out hover:-translate-y-2 hover:shadow-none dark:border-gray-700'>
<div <div
className={classNames( className={classNames(
'flex h-full cursor-pointer flex-col items-center justify-center p-4 pt-8 transition duration-200 ease-in-out', 'flex h-full cursor-pointer flex-col items-center justify-center p-4 pt-8 transition duration-200 ease-in-out',
@ -83,9 +83,9 @@ export const GuildPublic: React.FC<GuildPublicProps> = (props) => {
{guild.description != null ? ( {guild.description != null ? (
guild.description guild.description
) : ( ) : (
<span className='flex h-full items-center justify-center opacity-25'> <span className='flex h-full items-center justify-center opacity-40 dark:opacity-20'>
<Emoji value=':eyes:' size={25} /> <Emoji value=':eyes:' size={25} />
<span className='ml-2'>Nothing&apos;s here...</span> <span className='ml-2'>{t('application:nothing-here')}</span>
</span> </span>
)} )}
</p> </p>

View File

@ -52,12 +52,12 @@ export const JoinGuildsPublic: React.FC = () => {
/> />
<div className='w-full p-12'> <div className='w-full p-12'>
<InfiniteScroll <InfiniteScroll
className='guilds-public-list mx-auto grid max-w-[1400px] grid-cols-[repeat(auto-fill,_minmax(20em,_1fr))] gap-8 !overflow-visible' className='guilds-public-list relative mx-auto grid max-w-[1400px] grid-cols-[repeat(auto-fill,_minmax(20em,_1fr))] gap-8 !overflow-visible'
dataLength={items.length} dataLength={items.length}
next={nextPage} next={nextPage}
scrollableTarget='application-page-content' scrollableTarget='application-page-content'
hasMore={hasMore} hasMore={hasMore}
loader={<Loader />} loader={<Loader className='absolute left-1/2 -translate-x-1/2' />}
> >
{items.map((guild) => { {items.map((guild) => {
return <GuildPublic guild={guild} key={guild.id} /> return <GuildPublic guild={guild} key={guild.id} />

View File

@ -1,6 +1,7 @@
import { useState, useRef } from 'react' import { useState, useRef } from 'react'
import useTranslation from 'next-translate/useTranslation' import useTranslation from 'next-translate/useTranslation'
import TextareaAutosize from 'react-textarea-autosize' import TextareaAutosize from 'react-textarea-autosize'
import classNames from 'classnames'
import { GuildsChannelsPath } from '..' import { GuildsChannelsPath } from '..'
import { useAuthentication } from '../../../tools/authentication' import { useAuthentication } from '../../../tools/authentication'
@ -77,9 +78,17 @@ export const SendMessage: React.FC<SendMessageProps> = (props) => {
} }
return ( return (
<> <div className='relative p-6 pb-4'>
{isVisibleEmojiPicker && <EmojiPicker onClick={handleEmojiPicker} />} <div
<div className='p-6 pb-4'> className={classNames(
'absolute bottom-24 right-20 z-50 w-fit transition-all duration-100',
{
'invisible translate-y-5 opacity-0': !isVisibleEmojiPicker
}
)}
>
<EmojiPicker onClick={handleEmojiPicker} />
</div>
<div className='flex h-full w-full rounded-lg bg-gray-200 py-1 text-gray-600 dark:bg-gray-800 dark:text-gray-200'> <div className='flex h-full w-full rounded-lg bg-gray-200 py-1 text-gray-600 dark:bg-gray-800 dark:text-gray-200'>
<form <form
className='flex h-full w-full items-center' className='flex h-full w-full items-center'
@ -121,6 +130,5 @@ export const SendMessage: React.FC<SendMessageProps> = (props) => {
</div> </div>
</div> </div>
</div> </div>
</>
) )
} }

View File

@ -1,5 +1,5 @@
import Image from 'next/image' import Image from 'next/image'
import { useState } from 'react' import React, { useState } from 'react'
import classNames from 'classnames' import classNames from 'classnames'
import date from 'date-and-time' import date from 'date-and-time'
import useTranslation from 'next-translate/useTranslation' import useTranslation from 'next-translate/useTranslation'
@ -22,8 +22,8 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
const { user, guilds } = props const { user, guilds } = props
const { t } = useTranslation() const { t } = useTranslation()
const [showPopup, setShowPopup] = useState<boolean>(false) const [showPopup, setShowPopup] = useState(false)
const [confirmation, setConfirmation] = useState<boolean>(false) const [confirmation, setConfirmation] = useState(false)
const handleConfirmationState = (): void => { const handleConfirmationState = (): void => {
setConfirmation((confirmation) => !confirmation) setConfirmation((confirmation) => !confirmation)
@ -60,7 +60,7 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
<div className='ml-10 flex flex-col'> <div className='ml-10 flex flex-col'>
<div className='mb-2 flex items-center'> <div className='mb-2 flex items-center'>
<p <p
className='space text-3xl font-bold tracking-wide text-white' className='space text-dark text-3xl font-bold tracking-wide dark:text-white'
data-cy='user-name' data-cy='user-name'
> >
{user.name} {user.name}
@ -125,12 +125,11 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
</div> </div>
</div> </div>
{/* TODO: We might want to remove this code */}
<div <div
className={classNames( className={classNames(
'pointer-events-none absolute top-0 flex h-full w-full items-center justify-center bg-zinc-900/75 opacity-0 transition', 'pointer-events-none invisible absolute top-0 flex h-full w-full items-center justify-center bg-zinc-900/75 opacity-0 transition',
{ {
'pointer-events-auto visible opacity-100': showPopup 'pointer-events-auto !visible !opacity-100': showPopup
} }
)} )}
> >
@ -161,8 +160,8 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
</div> </div>
<XIcon <XIcon
height={40} height={40}
onClick={() => setShowPopup(false)} onClick={handlePopupVisibility}
className='absolute top-8 right-8 cursor-pointer transition hover:rotate-180' className='absolute top-8 right-8 cursor-pointer text-white transition hover:rotate-90'
/> />
</div> </div>
</div> </div>

View File

@ -1,18 +1,22 @@
import Image from 'next/image' import Image from 'next/image'
import { LoginIcon } from '@heroicons/react/solid' import { LoginIcon } from '@heroicons/react/solid'
import classNames from 'classnames'
export interface UserProfileGuildProps { export interface UserProfileGuildProps {
className?: string className?: string
handleConfirmationState: () => void handleConfirmationState: () => void
} }
export const UserProfileGuild: React.FC<UserProfileGuildProps> = (props) => { export const UserProfileGuild: React.FC<UserProfileGuildProps> = ({
const { handleConfirmationState } = props ...props
}) => {
return ( return (
<div <div
className='group relative flex w-full cursor-pointer transition' className={classNames(
onClick={handleConfirmationState} 'group relative flex w-full cursor-pointer transition',
props.className
)}
onClick={props.handleConfirmationState}
> >
<div className='relative w-full px-8 py-5 transition group-hover:-translate-x-20'> <div className='relative w-full px-8 py-5 transition group-hover:-translate-x-20'>
<div className='flex transition group-hover:opacity-40'> <div className='flex transition group-hover:opacity-40'>
@ -28,7 +32,7 @@ export const UserProfileGuild: React.FC<UserProfileGuildProps> = (props) => {
</div> </div>
<div className='flex flex-col'> <div className='flex flex-col'>
<h1 className='text-xl font-bold'>Guild Name</h1> <h1 className='text-xl font-bold'>Guild Name</h1>
<p className='mt-2 text-gray-300'> <p className='mt-2 text-gray-900 dark:text-gray-300'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis, Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis,
nam. nam.
</p> </p>

View File

@ -1,13 +1,14 @@
export interface LoaderProps { export interface LoaderProps {
width?: number width?: number
height?: number height?: number
className?: string
} }
export const Loader: React.FC<LoaderProps> = (props) => { export const Loader: React.FC<LoaderProps> = (props) => {
const { width = 50, height = 50 } = props const { width = 50, height = 50 } = props
return ( return (
<> <div className={props.className}>
<div data-testid='progress-spinner' className='progress-spinner'> <div data-testid='progress-spinner' className='progress-spinner'>
<svg className='progress-spinner-svg' viewBox='25 25 50 50'> <svg className='progress-spinner-svg' viewBox='25 25 50 50'>
<circle <circle
@ -29,7 +30,6 @@ export const Loader: React.FC<LoaderProps> = (props) => {
margin: 0 auto; margin: 0 auto;
width: ${width}px; width: ${width}px;
height: ${height}px; height: ${height}px;
display: inline-block;
} }
.progress-spinner::before { .progress-spinner::before {
content: ''; content: '';
@ -76,6 +76,6 @@ export const Loader: React.FC<LoaderProps> = (props) => {
} }
`} `}
</style> </style>
</> </div>
) )
} }

View File

@ -5,6 +5,7 @@
"create-a-guild": "Create a Guild", "create-a-guild": "Create a Guild",
"create-a-guild-description": "Create your own guild and manage everything.", "create-a-guild-description": "Create your own guild and manage everything.",
"join-a-guild": "Join a Guild", "join-a-guild": "Join a Guild",
"join-the-guild": "Join the guild",
"join-a-guild-description": "Talk, collaborate, share and have fun with your friends by joining an already existing guild!", "join-a-guild-description": "Talk, collaborate, share and have fun with your friends by joining an already existing guild!",
"members": "member(s)", "members": "member(s)",
"search": "Search", "search": "Search",
@ -12,5 +13,6 @@
"biography": "Biography", "biography": "Biography",
"label-checkbox-email": "Show your email to everyone.", "label-checkbox-email": "Show your email to everyone.",
"label-checkbox-guilds": "Show the list of guilds to everyone.", "label-checkbox-guilds": "Show the list of guilds to everyone.",
"private-user-guilds-list": "List of private guilds" "private-user-guilds-list": "List of private guilds",
"nothing-here": "Nothing's here..."
} }

View File

@ -3,5 +3,7 @@
"french": "French", "french": "French",
"all-rights-reserved": "All rights reserved", "all-rights-reserved": "All rights reserved",
"description": "Stay close with your friends and communities, talk, chat, collaborate, share, and have fun.", "description": "Stay close with your friends and communities, talk, chat, collaborate, share, and have fun.",
"name": "Name" "name": "Name",
"yes": "Yes",
"no": "No"
} }

View File

@ -5,6 +5,7 @@
"create-a-guild": "Créer une Guilde", "create-a-guild": "Créer une Guilde",
"create-a-guild-description": "Créez votre propre guilde et gérez tout.", "create-a-guild-description": "Créez votre propre guilde et gérez tout.",
"join-a-guild": "Rejoindre une Guilde", "join-a-guild": "Rejoindre une Guilde",
"join-the-guild": "Rejoindre la guilde",
"join-a-guild-description": "Discutez, collaborez, partagez et amusez-vous avec vos amis en rejoignant une guilde déjà existante!", "join-a-guild-description": "Discutez, collaborez, partagez et amusez-vous avec vos amis en rejoignant une guilde déjà existante!",
"members": "membre(s)", "members": "membre(s)",
"search": "Rechercher", "search": "Rechercher",
@ -12,5 +13,6 @@
"biography": "Biographie", "biography": "Biographie",
"label-checkbox-email": "Afficher votre email au public.", "label-checkbox-email": "Afficher votre email au public.",
"label-checkbox-guilds": "Afficher la liste des guildes au public.", "label-checkbox-guilds": "Afficher la liste des guildes au public.",
"private-user-guilds-list": "Liste des guildes privées" "private-user-guilds-list": "Liste des guildes privées",
"nothing-here": "Il n'y a rien ici..."
} }

View File

@ -3,5 +3,7 @@
"french": "Français", "french": "Français",
"all-rights-reserved": "Tous droits réservés", "all-rights-reserved": "Tous droits réservés",
"description": "Restez proche de vos amis et de vos communautés, parlez, collaborez, partagez et amusez-vous.", "description": "Restez proche de vos amis et de vos communautés, parlez, collaborez, partagez et amusez-vous.",
"name": "Nom" "name": "Nom",
"yes": "Yes",
"no": "Non"
} }

View File

@ -45,5 +45,5 @@ body,
.scrollbar-firefox-support { .scrollbar-firefox-support {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: var(--scroll-bar-color) var(--scroll-bar-bg-color); scrollbar-color: var(--scroll-bar-color) var(--scroll-bar-bg-color);
z-index: 1000; z-index: 0;
} }