8 Commits

16 changed files with 132 additions and 96 deletions

View File

@ -18,7 +18,7 @@
Thream's website to stay close with your friends and communities. Thream's website to stay close with your friends and communities.
It uses [Thream/api](https://github.com/Thream/api) [v1.0.0](https://github.com/Thream/api/releases/tag/v1.0.0). It uses [Thream/api](https://github.com/Thream/api) [v1.0.1](https://github.com/Thream/api/releases/tag/v1.0.1).
## ⚙️ Getting Started ## ⚙️ Getting Started

View File

@ -121,6 +121,7 @@ export const Application: React.FC<ApplicationProps> = (props) => {
}) })
}, },
onSwipedLeft: () => { onSwipedLeft: () => {
if (isGuildsChannelsPath(path)) {
if (visibleSidebars.left) { if (visibleSidebars.left) {
return setVisibleSidebars({ ...visibleSidebars, left: false }) return setVisibleSidebars({ ...visibleSidebars, left: false })
} }
@ -129,6 +130,7 @@ export const Application: React.FC<ApplicationProps> = (props) => {
right: true right: true
}) })
} }
}
}) })
useEffect(() => { useEffect(() => {

View File

@ -2,6 +2,7 @@ import { useRouter } from 'next/router'
import { useState } from 'react' import { useState } from 'react'
import { Form } from 'react-component-form' import { Form } from 'react-component-form'
import useTranslation from 'next-translate/useTranslation' import useTranslation from 'next-translate/useTranslation'
import axios from 'axios'
import { HandleSubmitCallback, useForm } from '../../../hooks/useForm' import { HandleSubmitCallback, useForm } from '../../../hooks/useForm'
import { FormState } from '../../design/FormState' import { FormState } from '../../design/FormState'
@ -81,9 +82,13 @@ export const ChannelSettings: React.FC<ChannelSettingsProps> = (props) => {
await router.push(`/application/${guild.id}/${data.defaultChannelId}`) await router.push(`/application/${guild.id}/${data.defaultChannelId}`)
} catch (error) { } catch (error) {
setFetchState('error') setFetchState('error')
if (axios.isAxiosError(error) && error.response?.status === 400) {
setMessageTranslationKey('application:delete-channel-only-one')
} else {
setMessageTranslationKey('errors:server-error') setMessageTranslationKey('errors:server-error')
} }
} }
}
return ( return (
<Form <Form

View File

@ -16,11 +16,12 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<>
<div className='relative flex h-full flex-col items-center justify-center'> <div className='relative flex h-full flex-col items-center justify-center'>
<div className='transition'> <div className='transition'>
<div className='max-w-[1000px] px-12'> <div className='max-w-[1000px] px-12'>
<div className='flex items-center justify-between'> <div className='flex items-center justify-between'>
<div className='flex w-max items-center'> <div className='flex w-max flex-col items-center gap-7 md:flex-row'>
<div className='relative flex items-center justify-center overflow-hidden rounded-full shadow-lg transition-all'> <div className='relative flex items-center justify-center overflow-hidden rounded-full shadow-lg transition-all'>
<Image <Image
quality={100} quality={100}
@ -89,11 +90,20 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
</div> </div>
</div> </div>
</div> </div>
<div className='mt-7'> {user.biography != null && (
{user.biography != null && <p>{user.biography}</p>} <div className='mt-7 text-center'>
</div> <p>{user.biography}</p>
</div>
)}
</div> </div>
</div> </div>
</div> </div>
<style jsx global>{`
#application-page-content {
overflow-x: hidden;
}
`}</style>
</>
) )
} }

View File

@ -84,7 +84,10 @@ export const UserSettings: React.FC = () => {
return { return {
...oldUser, ...oldUser,
...userCurrentData, ...userCurrentData,
settings: userCurrentSettings.settings settings: {
...oldUser.settings,
...userCurrentSettings.settings
}
} }
}) })
return { return {

View File

@ -2,8 +2,12 @@
"website": "Website", "website": "Website",
"create": "Create", "create": "Create",
"status": "Status", "status": "Status",
"create-a-channel": "Create a channel",
"delete-channel-only-one": "The guild should have at least one channel. You can't delete the only channel of the guild.",
"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.",
"user-settings": "User settings",
"guild-settings": "Guild settings",
"join-a-guild": "Join a Guild", "join-a-guild": "Join a Guild",
"join-the-guild": "Join the 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!",

View File

@ -2,8 +2,12 @@
"website": "Site web", "website": "Site web",
"create": "Créer", "create": "Créer",
"status": "Statut", "status": "Statut",
"create-a-channel": "Créer un channel",
"delete-channel-only-one": "La guilde doit avoir au moins un channel. Vous ne pouvez pas supprimer le seul channel de la guilde.",
"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.",
"user-settings": "Paramètres utilisateur",
"guild-settings": "Paramètres de la guilde",
"join-a-guild": "Rejoindre une Guilde", "join-a-guild": "Rejoindre une Guilde",
"join-the-guild": "Rejoindre la 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!",

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@thream/website", "name": "@thream/website",
"version": "1.0.0", "version": "1.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@thream/website", "name": "@thream/website",
"version": "1.0.0", "version": "1.0.2",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@fontsource/montserrat": "4.5.7", "@fontsource/montserrat": "4.5.7",

View File

@ -1,6 +1,6 @@
{ {
"name": "@thream/website", "name": "@thream/website",
"version": "1.0.0", "version": "1.0.2",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -43,7 +43,7 @@ const ChannelPage: NextPage<ChannelPageProps> = (props) => {
<MembersProviders path={path}> <MembersProviders path={path}>
<ChannelsProvider path={path}> <ChannelsProvider path={path}>
<MessagesProvider path={path}> <MessagesProvider path={path}>
<Head title='Thream | Application' /> <Head title={`Thream | ${selectedChannel.name}`} />
<Application <Application
path={path} path={path}
guildLeftSidebar={<GuildLeftSidebar path={path} />} guildLeftSidebar={<GuildLeftSidebar path={path} />}

View File

@ -40,7 +40,7 @@ const ChannelSettingsPage: NextPage<ChannelSettingsPageProps> = (props) => {
<GuildMemberProvider guildMember={guildMember} path={path}> <GuildMemberProvider guildMember={guildMember} path={path}>
<MembersProviders path={path}> <MembersProviders path={path}>
<ChannelsProvider path={path}> <ChannelsProvider path={path}>
<Head title='Thream | Application' /> <Head title={`Thream | ${selectedChannel.name}`} />
<Application <Application
path={path} path={path}
guildLeftSidebar={<GuildLeftSidebar path={path} />} guildLeftSidebar={<GuildLeftSidebar path={path} />}

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next' import { NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { Head } from '../../../../components/Head' import { Head } from '../../../../components/Head'
import { Application } from '../../../../components/Application' import { Application } from '../../../../components/Application'
@ -21,6 +22,7 @@ export interface CreateChannelPageProps extends PagePropsWithAuthentication {
const CreateChannelPage: NextPage<CreateChannelPageProps> = (props) => { const CreateChannelPage: NextPage<CreateChannelPageProps> = (props) => {
const { guildId, authentication, guildMember } = props const { guildId, authentication, guildMember } = props
const { t } = useTranslation()
const path = { guildId } const path = { guildId }
@ -29,10 +31,10 @@ const CreateChannelPage: NextPage<CreateChannelPageProps> = (props) => {
<GuildsProvider> <GuildsProvider>
<GuildMemberProvider guildMember={guildMember} path={path}> <GuildMemberProvider guildMember={guildMember} path={path}>
<Head <Head
title={`Thream | Crée un channel`} title={`Thream | ${t('application:create-a-channel')}`}
description={'Crée un nouveau channel'} description={t('application:create-a-channel')}
/> />
<Application path={path} title={'Crée un channel'}> <Application path={path} title={t('application:create-a-channel')}>
<CreateChannel /> <CreateChannel />
</Application> </Application>
</GuildMemberProvider> </GuildMemberProvider>

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next' import { NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { Head } from '../../../components/Head' import { Head } from '../../../components/Head'
import { Application } from '../../../components/Application' import { Application } from '../../../components/Application'
@ -18,6 +19,7 @@ export interface GuildSettingsPageProps extends PagePropsWithAuthentication {
const GuildSettingsPage: NextPage<GuildSettingsPageProps> = (props) => { const GuildSettingsPage: NextPage<GuildSettingsPageProps> = (props) => {
const { guildId, authentication, guildMember } = props const { guildId, authentication, guildMember } = props
const { t } = useTranslation()
const path = { guildId } const path = { guildId }
@ -25,8 +27,8 @@ const GuildSettingsPage: NextPage<GuildSettingsPageProps> = (props) => {
<AuthenticationProvider authentication={authentication}> <AuthenticationProvider authentication={authentication}>
<GuildsProvider> <GuildsProvider>
<GuildMemberProvider guildMember={guildMember} path={path}> <GuildMemberProvider guildMember={guildMember} path={path}>
<Head title='Thream | Guild settings' /> <Head title={`Thream | ${t('application:guild-settings')}`} />
<Application path={path} title='Guild settings'> <Application path={path} title={t('application:guild-settings')}>
<GuildSettings /> <GuildSettings />
</Application> </Application>
</GuildMemberProvider> </GuildMemberProvider>

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next' import { NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { Head } from '../../../components/Head' import { Head } from '../../../components/Head'
import { Application } from '../../../components/Application' import { Application } from '../../../components/Application'
@ -11,11 +12,16 @@ import { UserSettings } from '../../../components/Application/UserSettings'
import { GuildsProvider } from '../../../contexts/Guilds' import { GuildsProvider } from '../../../contexts/Guilds'
const UserSettingsPage: NextPage<PagePropsWithAuthentication> = (props) => { const UserSettingsPage: NextPage<PagePropsWithAuthentication> = (props) => {
const { t } = useTranslation()
return ( return (
<AuthenticationProvider authentication={props.authentication}> <AuthenticationProvider authentication={props.authentication}>
<GuildsProvider> <GuildsProvider>
<Head title='Thream | Settings' /> <Head title={`Thream | ${t('application:user-settings')}`} />
<Application path={`/application/users/settings`} title='Settings'> <Application
path='/application/users/settings'
title={t('application:user-settings')}
>
<UserSettings /> <UserSettings />
</Application> </Application>
</GuildsProvider> </GuildsProvider>

View File

@ -1,6 +1,6 @@
import axios from 'axios' import axios from 'axios'
export const API_VERSION = '1.0.0' export const API_VERSION = '1.0.1'
export const API_DEFAULT_PORT = 8080 export const API_DEFAULT_PORT = 8080

View File

@ -5,7 +5,6 @@ import useTranslation from 'next-translate/useTranslation'
import { Authentication, PagePropsWithAuthentication } from '.' import { Authentication, PagePropsWithAuthentication } from '.'
import { UserCurrent } from '../../models/User' import { UserCurrent } from '../../models/User'
import { Language, Theme } from '../../models/UserSettings'
export interface AuthenticationValue { export interface AuthenticationValue {
authentication: Authentication authentication: Authentication
@ -41,14 +40,13 @@ export const AuthenticationProvider: React.FC<PagePropsWithAuthentication> = (
useEffect(() => { useEffect(() => {
authentication.api authentication.api
.put('/users/current/settings', { theme, language: lang }) .put('/users/current/settings', { theme, language: lang })
.then(() => { .then(({ data: userCurrentSettings }) => {
setUser((oldUser) => { setUser((oldUser) => {
return { return {
...oldUser, ...oldUser,
settings: { settings: {
...oldUser.settings, ...oldUser.settings,
theme: theme as Theme, ...userCurrentSettings.settings
language: lang as Language
} }
} }
}) })