fix: improve overall rendering v3 (#25)
Follow-up of #15 Co-authored-by: Walidoux <ma.walidkorchi@icloud.com>
This commit is contained in:
@ -184,6 +184,7 @@ export const Application: React.FC<ApplicationProps> = (props) => {
|
||||
title='Settings'
|
||||
>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full'
|
||||
src={
|
||||
user.logo == null
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
import { channelExample } from '../../../../cypress/fixtures/channels/channel'
|
||||
import { Channel } from './Channel'
|
||||
|
||||
describe('<Channel />', () => {
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(
|
||||
<Channel channel={channelExample} path={{ channelId: 1, guildId: 1 }} />
|
||||
)
|
||||
expect(baseElement).toBeTruthy()
|
||||
})
|
||||
})
|
@ -1,8 +1,12 @@
|
||||
import classNames from 'classnames'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { CogIcon } from '@heroicons/react/solid'
|
||||
|
||||
import { GuildsChannelsPath } from '../../Application'
|
||||
import { Channel as ChannelType } from '../../../../models/Channel'
|
||||
import { useGuildMember } from '../../../../contexts/GuildMember'
|
||||
import { IconButton } from '../../../design/IconButton'
|
||||
|
||||
export interface ChannelProps {
|
||||
path: GuildsChannelsPath
|
||||
@ -12,20 +16,39 @@ export interface ChannelProps {
|
||||
|
||||
export const Channel: React.FC<ChannelProps> = (props) => {
|
||||
const { channel, path, selected = false } = props
|
||||
const router = useRouter()
|
||||
|
||||
const { member } = useGuildMember()
|
||||
|
||||
return (
|
||||
<Link href={`/application/${path.guildId}/${channel.id}`}>
|
||||
<a
|
||||
className={classNames(
|
||||
'group my-3 mx-3 flex items-center justify-between rounded-lg py-2 text-sm transition-colors duration-200 hover:bg-gray-100 dark:hover:bg-gray-600',
|
||||
'group relative my-3 mx-3 flex items-center justify-between overflow-hidden rounded-lg py-2 text-sm transition-all duration-200 hover:bg-gray-100 dark:hover:bg-gray-600',
|
||||
{
|
||||
'font-semibold text-green-800 dark:text-green-400': selected
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span className='ml-2 mr-4' data-cy='channel-name'>
|
||||
<span
|
||||
className='max-[315px] ml-2 mr-4 break-all'
|
||||
data-cy='channel-name'
|
||||
>
|
||||
# {channel.name}
|
||||
</span>
|
||||
{member.isOwner && (
|
||||
<IconButton
|
||||
onClick={async () => {
|
||||
await router.push(
|
||||
`/application/${channel.guildId}/${channel.id}/settings`
|
||||
)
|
||||
}}
|
||||
className='bg-unherit absolute -right-10 h-full w-8 transition-all group-hover:right-0 group-hover:shadow-lg dark:group-hover:bg-gray-600'
|
||||
title='Settings'
|
||||
>
|
||||
<CogIcon height={20} width={20} />
|
||||
</IconButton>
|
||||
)}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
|
@ -38,6 +38,7 @@ export const ConfirmGuildJoin: React.FC<ConfirmGuildJoinProps> = ({
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
quality={100}
|
||||
src='/images/svg/design/join-guild.svg'
|
||||
alt='Join Guild Illustration'
|
||||
height={150}
|
||||
|
@ -50,7 +50,7 @@ export const GuildSettings: React.FC = () => {
|
||||
setInputValues(formData as any)
|
||||
return {
|
||||
type: 'success',
|
||||
value: 'common:name'
|
||||
value: 'application:saved-information'
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
@ -130,6 +130,7 @@ export const GuildSettings: React.FC = () => {
|
||||
</div>
|
||||
<div className='flex items-center justify-center rounded-full bg-black shadow-xl'>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full opacity-50'
|
||||
src={
|
||||
guild.icon == null
|
||||
@ -193,7 +194,10 @@ export const GuildSettings: React.FC = () => {
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<FormState state={fetchState} message={message} />
|
||||
<FormState
|
||||
state={fetchState}
|
||||
message={getErrorTranslation(errors.description) ?? message}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
)
|
||||
|
@ -21,6 +21,7 @@ export const Guild: React.FC<GuildProps> = (props) => {
|
||||
>
|
||||
<div className='pl-[6px]'>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full'
|
||||
src={
|
||||
guild.icon != null
|
||||
|
@ -61,6 +61,7 @@ export const GuildPublic: React.FC<GuildPublicProps> = (props) => {
|
||||
onClick={handleIsConfirmed}
|
||||
>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full'
|
||||
src={
|
||||
guild.icon != null
|
||||
|
@ -33,9 +33,7 @@ export const Member: React.FC<MemberProps> = (props) => {
|
||||
<p data-cy='member-user-name' className='truncate font-bold'>
|
||||
{member.user.name}
|
||||
</p>
|
||||
{member.user.status != null && (
|
||||
<span className='block w-44 truncate'>{member.user.status}</span>
|
||||
)}
|
||||
{member.user.status != null && member.user.status}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -25,6 +25,7 @@ export const Message: React.FC<MessageProps> = (props) => {
|
||||
<div className='mr-4 flex h-12 w-12 flex-shrink-0 items-center justify-center'>
|
||||
<div className='h-10 w-10 drop-shadow-md'>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full'
|
||||
src={
|
||||
message.member.user.logo == null
|
||||
|
@ -23,6 +23,7 @@ export const PopupGuild: React.FC<PopupGuildProps> = (props) => {
|
||||
<PopupGuildCard
|
||||
image={
|
||||
<Image
|
||||
quality={100}
|
||||
src='/images/svg/design/create-guild.svg'
|
||||
alt={t('application:create-a-guild')}
|
||||
draggable='false'
|
||||
@ -40,6 +41,7 @@ export const PopupGuild: React.FC<PopupGuildProps> = (props) => {
|
||||
<PopupGuildCard
|
||||
image={
|
||||
<Image
|
||||
quality={100}
|
||||
src='/images/svg/design/join-guild.svg'
|
||||
alt={t('application:join-a-guild')}
|
||||
draggable='false'
|
||||
|
@ -10,6 +10,7 @@ describe('<PopupGuildCard />', () => {
|
||||
<PopupGuildCard
|
||||
image={
|
||||
<Image
|
||||
quality={100}
|
||||
src='/images/svg/design/create-server.svg'
|
||||
alt=''
|
||||
width={230}
|
||||
|
@ -104,7 +104,6 @@ export const SendMessage: React.FC<SendMessageProps> = (props) => {
|
||||
onChange={handleTextareaChange}
|
||||
value={message}
|
||||
ref={textareaReference}
|
||||
autoFocus
|
||||
/>
|
||||
</form>
|
||||
<div className='flex h-full items-center justify-around pr-6'>
|
||||
|
@ -24,6 +24,7 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
||||
<div className='flex w-max items-center'>
|
||||
<div className='relative flex items-center justify-center overflow-hidden rounded-full shadow-lg transition-all'>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full'
|
||||
src={
|
||||
user.logo != null
|
||||
|
@ -2,9 +2,10 @@ import Image from 'next/image'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
import { useState } from 'react'
|
||||
import { Form } from 'react-component-form'
|
||||
import { PhotographIcon } from '@heroicons/react/solid'
|
||||
import { EyeIcon, PhotographIcon } from '@heroicons/react/solid'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import axios from 'axios'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { API_URL } from '../../../tools/api'
|
||||
import { Input } from '../../design/Input'
|
||||
@ -17,7 +18,7 @@ import { useAuthentication } from '../../../tools/authentication'
|
||||
import { Button } from '../../design/Button'
|
||||
import { FormState } from '../../design/FormState'
|
||||
import { useForm, HandleSubmitCallback } from '../../../hooks/useForm'
|
||||
import { userCurrentSchema, userSchema } from '../../../models/User'
|
||||
import { userSchema } from '../../../models/User'
|
||||
import { userSettingsSchema } from '../../../models/UserSettings'
|
||||
|
||||
export const UserSettings: React.FC = () => {
|
||||
@ -45,7 +46,7 @@ export const UserSettings: React.FC = () => {
|
||||
validateSchema: {
|
||||
name: userSchema.name,
|
||||
status: Type.Optional(userSchema.status),
|
||||
email: Type.Optional(userCurrentSchema.email),
|
||||
email: Type.Optional(Type.Union([userSchema.email, Type.Null()])),
|
||||
website: Type.Optional(userSchema.website),
|
||||
biography: Type.Optional(userSchema.biography),
|
||||
isPublicGuilds: userSettingsSchema.isPublicGuilds,
|
||||
@ -63,6 +64,14 @@ export const UserSettings: React.FC = () => {
|
||||
`/users/current?redirectURI=${window.location.origin}/authentication/signin`,
|
||||
userData
|
||||
)
|
||||
setInputValues(formData as any)
|
||||
const hasEmailChanged = user.email !== userCurrentData.user.email
|
||||
if (hasEmailChanged) {
|
||||
return {
|
||||
type: 'success',
|
||||
value: 'application:success-email-changed'
|
||||
}
|
||||
}
|
||||
const { data: userCurrentSettings } = await authentication.api.put(
|
||||
'/users/current/settings',
|
||||
userSettings
|
||||
@ -74,10 +83,9 @@ export const UserSettings: React.FC = () => {
|
||||
settings: userCurrentSettings.settings
|
||||
}
|
||||
})
|
||||
setInputValues(formData as any)
|
||||
return {
|
||||
type: 'success',
|
||||
value: 'common:name'
|
||||
value: 'application:saved-information'
|
||||
}
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error) && error.response?.status === 400) {
|
||||
@ -185,6 +193,7 @@ export const UserSettings: React.FC = () => {
|
||||
</div>
|
||||
<div className='flex items-center justify-center rounded-full bg-black shadow-xl'>
|
||||
<Image
|
||||
quality={100}
|
||||
className='rounded-full opacity-50'
|
||||
src={
|
||||
user.logo != null
|
||||
@ -255,6 +264,24 @@ export const UserSettings: React.FC = () => {
|
||||
/>
|
||||
</div>
|
||||
<div className='flex h-full w-4/5 flex-col items-center justify-between pr-0 sm:w-[415px] lg:pl-12'>
|
||||
<div className='flex w-full items-center pt-14'>
|
||||
<Language className='!top-12' />
|
||||
<div className='ml-auto flex'>
|
||||
<SwitchTheme />
|
||||
<Link href={`/application/users/${user.id}`}>
|
||||
<a
|
||||
className='group ml-3 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-slate-200 transition-colors hover:bg-slate-300 dark:bg-slate-700 hover:dark:bg-slate-800'
|
||||
title='Preview Public Profile'
|
||||
>
|
||||
<EyeIcon
|
||||
height={20}
|
||||
className='opacity-50 transition-opacity group-hover:opacity-100'
|
||||
/>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-14 flex w-full flex-col gap-4'>
|
||||
<SocialMediaButton
|
||||
socialMedia='Google'
|
||||
@ -269,10 +296,6 @@ export const UserSettings: React.FC = () => {
|
||||
className='w-full justify-center'
|
||||
/>
|
||||
</div>
|
||||
<div className='flex w-full justify-between pt-14'>
|
||||
<Language />
|
||||
<SwitchTheme />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Reference in New Issue
Block a user