From 069c5ac5ee0508201c9986a5a29f9d2930e5a883 Mon Sep 17 00:00:00 2001 From: Nix13 Date: Sun, 11 Oct 2020 01:30:37 +0300 Subject: [PATCH] api types; navbar style refactoring; user themes --- package.json | 3 +- src/api/api.ts | 14 +-- src/api/auth.ts | 8 +- src/api/characters.ts | 4 +- src/api/users.ts | 19 ++-- .../AdminPanel/Users/AdminPanelUsers.tsx | 4 +- src/pages/App/App.tsx | 10 ++- src/pages/Comments/Comments.sass | 5 +- src/pages/Navbar/Navbar.sass | 19 +++- src/pages/Navbar/Navbar.tsx | 35 ++++---- src/pages/Novel/Novel.sass | 41 +-------- src/pages/User/Novels/UserNovels.tsx | 5 +- src/pages/User/Settings/Settings.tsx | 87 ++++++++++++++++--- src/pages/User/User.sass | 8 +- src/pages/User/User.tsx | 39 +++++++-- src/store/reducers/{index.ts => reducers.ts} | 0 src/store/store.ts | 6 +- src/types/api.d.ts | 29 +++++++ src/types/store.d.ts | 11 +++ src/{ => types}/types.d.ts | 14 +-- src/ui/Comment/Comment.sass | 2 +- src/ui/Tabs/TabItem.tsx | 13 +++ src/ui/Tabs/Tabs.sass | 14 +++ src/ui/Tabs/Tabs.tsx | 10 +++ tsconfig.json | 4 +- 25 files changed, 274 insertions(+), 130 deletions(-) rename src/store/reducers/{index.ts => reducers.ts} (100%) create mode 100644 src/types/api.d.ts create mode 100644 src/types/store.d.ts rename src/{ => types}/types.d.ts (81%) create mode 100644 src/ui/Tabs/TabItem.tsx create mode 100644 src/ui/Tabs/Tabs.sass create mode 100644 src/ui/Tabs/Tabs.tsx diff --git a/package.json b/package.json index 7e0d2dc..2eac14d 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "not op_mini all" ], "development": [ - "last 1 chrome version" + "last 1 chrome version", + "last 1 firefox version" ] } } diff --git a/src/api/api.ts b/src/api/api.ts index 93cd193..40061ee 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,6 +1,6 @@ const baseUrl = process.env.NODE_ENV === "development" ? 'http://localhost:8080/v1' : 'https://api.unmei.space/v1'; -const response = async (url: string, method: string, body?: string | FormData) => { +const request: ApiRequest = async (url: string, method: string, body?: string | FormData) => { let bUrl = baseUrl; if(baseUrl.endsWith('/')) bUrl = bUrl.slice(0, baseUrl.length-1); if(url.startsWith('/')) url = url.slice(1, baseUrl.length); @@ -18,17 +18,17 @@ const response = async (url: string, method: string, body?: string | FormData) = } if(res.status === 429) return new Promise(res => { - setTimeout(res.bind(null, response(url, method, body)), 1500); + setTimeout(res.bind(null, request(url, method, body)), 1500); }); if(json?.error) return Promise.reject(json.error_data); if(!res.ok) return Promise.reject(res.statusText); return Promise.resolve(json.data); } -const get = (url: string, data?: object) => response(url, 'GET', JSON.stringify(data)); -const post = (url: string, data?: object | FormData) => response(url, 'POST', data instanceof FormData ? data : JSON.stringify(data)); -const put = (url: string, data?: object) => response(url, 'PUT', JSON.stringify(data)); -const del = (url: string, data?: object) => response(url, 'DELETE', JSON.stringify(data)); +const get: Get = (url: string, data?: object) => request(url, 'GET', JSON.stringify(data)); +const post: Post = (url: string, data?: object | FormData) => request(url, 'POST', data instanceof FormData ? data : JSON.stringify(data)); +const put: Put = (url: string, data?: object) => request(url, 'PUT', JSON.stringify(data)); +const del: Delete = (url: string, data?: object) => request(url, 'DELETE', JSON.stringify(data)); const TranslateStatus: { [id: string]: string } = { planned: 'Запланировано', @@ -39,6 +39,6 @@ const TranslateStatus: { [id: string]: string } = { }; export const getVersion = () => get('version'); -export const version = '0.10'; +export const version = '0.10b'; export { get, post, put, del, TranslateStatus }; diff --git a/src/api/auth.ts b/src/api/auth.ts index 2d92a8c..472fb76 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -1,6 +1,6 @@ import {post} from "./api"; -export const restore = (token: string, new_password: string) => post('auth/restore', { token, new_password }); -export const registerUser = (login: string, password: string, email: string, recaptcha: string) => post('auth/register', { login, password, email, recaptcha }); -export const login = (login: string, password: string, recaptcha: string) => post('auth/login', { login, password, recaptcha }); -export const userLogout = () => post('auth/logout'); +export const restore: Restore = (token: string, new_password: string) => post('auth/restore', { token, new_password }); +export const registerUser: Register = (login: string, password: string, email: string, recaptcha: string) => post('auth/register', { login, password, email, recaptcha }); +export const login: Login = (login: string, password: string, recaptcha: string) => post('auth/login', { login, password, recaptcha }); +export const userLogout: Logout = () => post('auth/logout'); diff --git a/src/api/characters.ts b/src/api/characters.ts index 30f0e78..00db177 100644 --- a/src/api/characters.ts +++ b/src/api/characters.ts @@ -1,4 +1,4 @@ import {get} from "./api"; -export const fetchChar = (id: number) => get(`characters/${id}`); -export const fetchCharNovels = (id: number) => get(`characters/${id}/novels`); \ No newline at end of file +export const fetchChar: FetchChar = (id: number) => get(`characters/${id}`); +export const fetchCharNovels: FetchCharNovels = (id: number) => get(`characters/${id}/novels`); diff --git a/src/api/users.ts b/src/api/users.ts index 1e5f14a..9e10d8d 100644 --- a/src/api/users.ts +++ b/src/api/users.ts @@ -1,18 +1,19 @@ import {get, post, put} from "./api"; -export const fetchUsers = () => get('users'); +export const fetchUsers: FetchUsers = () => get('users'); -export const fetchUser = (id: number) => get(`users/${id}`); -export const updateUser = (user: UserType) => put(`users/${user.id}`, { user }) +export const fetchUser: FetchUser = (id: number) => get(`users/${id}`); +export const updateUser: UpdateUser = (user: UserType) => put(`users/${user.id}`, { user }); -export const fetchCurrentUser = () => get('users/me'); -export const fetchUserNovels = (id: number) => get(`users/${id}/novels`); +export const fetchCurrentUser: FetchCurrentUser = () => get('users/me'); +export const fetchUserNovels: FetchUserNovels = (id: number) => get(`users/${id}/novels`); -export const activateAccount = (token: string) => post('auth/activate', { token }); -export const generateActivateLink = () => post('auth/activateToken'); +export const activateAccount: ActivateAccount = (token: string) => post('auth/activate', { token }); +export const generateActivateLink: GenerateActivateLink = () => post('auth/activateToken'); -export const fetchUserSettings = () => get('users/me/settings'); -export const updateUserSettings = (use_gravatar: boolean, avatar: string) => post('users/me/settings', { use_gravatar, avatar }); +export const fetchUserSettings: FetchUserSettings = () => get('users/me/settings'); +export const updateUserGeneralSettings: UpdateUserGeneralSettings = (use_gravatar: boolean, avatar: string) => post('users/me/settings', { use_gravatar, avatar }); +export const updateUserAppearanceSettings: UpdateUserAppearanceSettings = (theme: string) => post('users/me/settings', { theme }); export const uploadAvatar = (avatar: FormData) => post('users/me/avatar', avatar); export const generateRestoreLink = (email: string, recaptcha: string) => post('auth/restoreToken', { email, recaptcha }); diff --git a/src/pages/AdminPanel/Users/AdminPanelUsers.tsx b/src/pages/AdminPanel/Users/AdminPanelUsers.tsx index 5a2851f..ab1a406 100644 --- a/src/pages/AdminPanel/Users/AdminPanelUsers.tsx +++ b/src/pages/AdminPanel/Users/AdminPanelUsers.tsx @@ -17,7 +17,7 @@ class AdminPanelUsers extends React.Component { } componentDidMount() { - fetchUsers().then(users => this.setState({ users })) + fetchUsers().then(users => this.setState({ users })); } render() { @@ -46,4 +46,4 @@ export default connect( (state: StoreState) => ({ user: state.currentUser }) -)(AdminPanelUsers); \ No newline at end of file +)(AdminPanelUsers); diff --git a/src/pages/App/App.tsx b/src/pages/App/App.tsx index 79187f8..3e147a1 100644 --- a/src/pages/App/App.tsx +++ b/src/pages/App/App.tsx @@ -41,11 +41,19 @@ class App extends React.Component { constructor(props: Props) { super(props); + const cachedTheme = localStorage.getItem('theme'); + if(cachedTheme) + document.body.setAttribute('theme', cachedTheme); + const { setUser } = this.props; fetchCurrentUser().then((user: UserType) => { setUser(user); fetchUserSettings().then((settings: UserSettingsType) => { - document.body.setAttribute('theme', settings.theme); + console.log(settings.theme, cachedTheme) + if(settings.theme !== cachedTheme) { + localStorage.setItem('theme', settings.theme); + document.body.setAttribute('theme', settings.theme); + } }); }).catch((err: ApiError) => { if(err.code !== 3 && err.text) console.error(err.text); diff --git a/src/pages/Comments/Comments.sass b/src/pages/Comments/Comments.sass index 5e8c4ec..7356c55 100644 --- a/src/pages/Comments/Comments.sass +++ b/src/pages/Comments/Comments.sass @@ -1,5 +1,5 @@ @import '../../Constants' - + .Comments margin-top: 1rem padding: $primaryPadding @@ -28,6 +28,7 @@ .Comments_TextArea width: 100% + color: var(--main-color) background-color: var(--block-color) font-size: 1rem padding: .25rem @@ -43,4 +44,4 @@ border-radius: .2rem border: none font-size: 1rem - padding: .5rem \ No newline at end of file + padding: .5rem diff --git a/src/pages/Navbar/Navbar.sass b/src/pages/Navbar/Navbar.sass index 5943b4e..ac600f0 100644 --- a/src/pages/Navbar/Navbar.sass +++ b/src/pages/Navbar/Navbar.sass @@ -10,7 +10,7 @@ $hoverColor: #f22 position: relative width: 100% -.Header +.Navbar color: var(--main-color) background-color: var(--nav-bg-color) display: flex @@ -52,6 +52,21 @@ $hoverColor: #f22 &::before height: 5px + &__Dropdown + cursor: pointer + + &:hover>&_Menu + display: block + + &_Menu + display: none + position: absolute + background-color: #fefefe + box-sizing: border-box + padding: .5rem + + &_Item + margin: .2rem 0 &__User justify-content: flex-end @@ -90,4 +105,4 @@ $hoverColor: #f22 width: 40px height: 40px border-radius: 50% - margin-right: .2rem \ No newline at end of file + margin-right: .2rem diff --git a/src/pages/Navbar/Navbar.tsx b/src/pages/Navbar/Navbar.tsx index cd8fd04..9329ba3 100644 --- a/src/pages/Navbar/Navbar.tsx +++ b/src/pages/Navbar/Navbar.tsx @@ -11,7 +11,7 @@ import RegisterModal from "../Modals/RegisterModal"; import LoginModal from "../Modals/LoginModal"; type Props = { - setModal: SetModalType + setModal: SetModal logout: () => void currentUser: UserType }; @@ -50,48 +50,45 @@ class Navbar extends React.Component { const isMinimized = window.screen.width <= 1000; const links = ( -
- +
+ Главная - + Новеллы - - Пользователи - {expand && isMinimized && ( -
X
+
X
)}
); return ( -