diff --git a/package-lock.json b/package-lock.json index ee4e1a7..7bb3422 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3944,9 +3944,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001146", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz", - "integrity": "sha512-VAy5RHDfTJhpxnDdp2n40GPPLp3KqNrXz1QqFv4J64HvArKs8nuNMOWkB3ICOaBTU/Aj4rYAo/ytdQDDFF/Pug==", + "version": "1.0.30001147", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001147.tgz", + "integrity": "sha512-CPyN875geYk46eIqPl5jlmotCr5YZC2KxIVfb4z0FrNfLxPM+MyodWD2irJGDG8vUUE1fmg3De9vt8uaC6Nf6w==", "dev": true }, "capture-exit": { @@ -4791,9 +4791,9 @@ } }, "css-what": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.1.tgz", - "integrity": "sha512-wHOppVDKl4vTAOWzJt5Ek37Sgd9qq1Bmj/T1OjvicWbU5W7ru7Pqbn0Jdqii3Drx/h+dixHKXNhZYx7blthL7g==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", "dev": true }, "cssdb": { @@ -13914,9 +13914,9 @@ }, "dependencies": { "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", diff --git a/src/api/api.ts b/src/api/api.ts index f449353..ac931fc 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,6 +1,6 @@ -const baseUrl = process.env.NODE_ENV === "development" ? 'http://192.168.0.103:8080/v1' : 'https://api.unmei.space/v1'; +const baseUrl = process.env.NODE_ENV === "development" ? 'http://localhost:8080/v1' : 'https://api.unmei.space/v1'; -const request: ApiRequest = async (url: string, method: string, body?: string | FormData) => { +async function request(url: string, method: string, body?: string | FormData): Promise { let bUrl = baseUrl; if(baseUrl.endsWith('/')) bUrl = bUrl.slice(0, baseUrl.length-1); if(url.startsWith('/')) url = url.slice(1, baseUrl.length); @@ -10,7 +10,7 @@ const request: ApiRequest = async (url: string, method: string, body?: string | credentials: "include" }); - let json: ApiResponse; + let json: ApiResponse; try { json = await res.json(); } catch (e) { @@ -22,13 +22,22 @@ const request: ApiRequest = async (url: string, method: string, body?: string | }); if(json?.error) return Promise.reject(json.error_data); if(!res.ok) return Promise.reject(res.statusText); + if(!json.data) return Promise.reject(null); return Promise.resolve(json.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)); +function get(url: string, data?: object): Promise { + return request(url, 'GET', JSON.stringify(data)); +} +function post(url: string, data?: object | FormData): Promise { + return request(url, 'POST', data instanceof FormData ? data : JSON.stringify(data)); +} +function put(url: string, data?: object): Promise { + return request(url, 'PUT', JSON.stringify(data)); +} +function del(url: string, data?: object): Promise { + return request(url, 'DELETE', JSON.stringify(data)); +} const TranslateStatus: { [id: string]: string } = { planned: 'Запланировано', @@ -38,7 +47,15 @@ const TranslateStatus: { [id: string]: string } = { deferred: 'Отложено' }; -export const getVersion = () => get('version'); +const TranslatePlatform: { [id: string]: string } = { + win: 'Windows' +}; + +const TranslateExitStatus: { [id: string]: string } = { + came_out: 'Вышла' +} + +export const getVersion = () => get('version'); export const version = '0.10b'; -export { get, post, put, del, TranslateStatus }; +export { get, post, put, del, TranslateStatus, TranslatePlatform, TranslateExitStatus }; diff --git a/src/api/auth.ts b/src/api/auth.ts index 472fb76..76a1789 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -1,6 +1,6 @@ import {post} from "./api"; -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'); +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'); diff --git a/src/api/characters.ts b/src/api/characters.ts index 00db177..f9745e4 100644 --- a/src/api/characters.ts +++ b/src/api/characters.ts @@ -1,4 +1,4 @@ import {get} from "./api"; -export const fetchChar: FetchChar = (id: number) => get(`characters/${id}`); -export const fetchCharNovels: FetchCharNovels = (id: number) => get(`characters/${id}/novels`); +export const fetchChar = (id: number) => get(`characters/${id}`); +export const fetchCharNovels = (id: number) => get(`characters/${id}/novels`); diff --git a/src/api/news.ts b/src/api/news.ts index 168bef3..e4a3632 100644 --- a/src/api/news.ts +++ b/src/api/news.ts @@ -1,7 +1,7 @@ import {del, get, put} from './api'; -export const fetchNews = () => get('news'); +export const fetchNews = () => get('news'); -export const fetchPost = (id: number) => get(`news/${id}`); -export const updatePost = (post: PostType) => put(`news/${post.id}`, post); -export const deletePost = (id: number) => del(`news/${id}`); \ No newline at end of file +export const fetchPost = (id: number) => get(`news/${id}`); +export const updatePost = (post: PostType) => put(`news/${post.id}`, post); +export const deletePost = (id: number) => del(`news/${id}`); diff --git a/src/api/novels.ts b/src/api/novels.ts index ec38a90..f14e19f 100644 --- a/src/api/novels.ts +++ b/src/api/novels.ts @@ -1,20 +1,20 @@ import { get, post, put, del } from "./api"; -export const fetchNovels = (orderBy?: string) => get(orderBy ? `novels?sort=${orderBy}` : 'novels'); -export const createNovel = (novel: NovelType) => post('novels', { ...novel }); +export const fetchNovels = (orderBy?: string) => get(orderBy ? `novels?sort=${orderBy}` : 'novels'); +export const createNovel = (novel: NovelType) => post('novels', { ...novel }); -export const fetchNovel = (id: number) => get(`novels/${id}`); -export const updateNovel = (id: number, novel: NovelType) => put(`novels/${id}`, { ...novel }); +export const fetchNovel = (id: number) => get(`novels/${id}`); +export const updateNovel = (id: number, novel: NovelType) => put(`novels/${id}`, { ...novel }); -export const fetchNovelCharacters = (id: number) => get(`novels/${id}/characters`); +export const fetchNovelCharacters = (id: number) => get(`novels/${id}/characters`); -export const fetchNovelGenres = (id: number) => get(`novels/${id}/genres`); +export const fetchNovelGenres = (id: number) => get(`novels/${id}/genres`); -export const fetchNovelComments = (id: number, offset=0, count=5) => get(`novels/${id}/comments?offset=${offset}&count=${count}`); -export const postNovelComment = (id: number, text: string) => post(`novels/${id}/comments`, { text }); +export const fetchNovelComments = (id: number, offset=0, count=5) => get(`novels/${id}/comments?offset=${offset}&count=${count}`); +export const postNovelComment = (id: number, text: string) => post(`novels/${id}/comments`, { text }); -export const fetchUserNovel = (userId: number, novelId: number) => get(`users/${userId}/novels/${novelId}`); -export const createUserNovel = (userId: number, novelId: number, status='planned') => post(`users/${userId}/novels`, { novel_id: Number(novelId), status }); -export const updateUserNovel = (userId: number, novelId: number, data: { mark?: number; status?: string }) => put(`users/${userId}/novels/${novelId}`, data); -export const deleteUserNovel = (userId: number, novelId: number) => del(`users/${userId}/novels/${novelId}`); \ No newline at end of file +export const fetchUserNovel = (userId: number, novelId: number) => get(`users/${userId}/novels/${novelId}`); +export const createUserNovel = (userId: number, novelId: number, status='planned') => post(`users/${userId}/novels`, { novel_id: Number(novelId), status }); +export const updateUserNovel = (userId: number, novelId: number, data: { mark?: number; status?: string }) => put(`users/${userId}/novels/${novelId}`, data); +export const deleteUserNovel = (userId: number, novelId: number) => del(`users/${userId}/novels/${novelId}`); diff --git a/src/api/users.ts b/src/api/users.ts index 9e10d8d..17b0d7c 100644 --- a/src/api/users.ts +++ b/src/api/users.ts @@ -1,19 +1,19 @@ import {get, post, put} from "./api"; -export const fetchUsers: FetchUsers = () => get('users'); +export const fetchUsers = () => get('users'); -export const fetchUser: FetchUser = (id: number) => get(`users/${id}`); -export const updateUser: UpdateUser = (user: UserType) => put(`users/${user.id}`, { user }); +export const fetchUser = (id: number) => get(`users/${id}`); +export const updateUser = (user: UserType) => put(`users/${user.id}`, { user }); -export const fetchCurrentUser: FetchCurrentUser = () => get('users/me'); -export const fetchUserNovels: FetchUserNovels = (id: number) => get(`users/${id}/novels`); +export const fetchCurrentUser = () => get('users/me'); +export const fetchUserNovels = (id: number) => get(`users/${id}/novels`); -export const activateAccount: ActivateAccount = (token: string) => post('auth/activate', { token }); -export const generateActivateLink: GenerateActivateLink = () => post('auth/activateToken'); +export const activateAccount = (token: string) => post('auth/activate', { token }); +export const generateActivateLink = () => post('auth/activateToken'); -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 fetchUserSettings = () => get('users/me/settings'); +export const updateUserGeneralSettings = (use_gravatar: boolean, avatar: string) => post('users/me/settings', { use_gravatar, avatar }); +export const 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/Modals/LoadingModal.tsx b/src/pages/Modals/LoadingModal.tsx new file mode 100644 index 0000000..e361f2f --- /dev/null +++ b/src/pages/Modals/LoadingModal.tsx @@ -0,0 +1,12 @@ +import React from "react"; +// @ts-ignore +import Loader from 'react-loader-spinner'; +import Popout from "../../ui/Modal/Popout"; + +const LoadingModal = () => ( + + + +); + +export default LoadingModal; diff --git a/src/pages/Navbar/Navbar.sass b/src/pages/Navbar/Navbar.sass index ac600f0..a2fac3d 100644 --- a/src/pages/Navbar/Navbar.sass +++ b/src/pages/Navbar/Navbar.sass @@ -56,17 +56,25 @@ $hoverColor: #f22 cursor: pointer &:hover>&_Menu - display: block + display: flex + flex-direction: column &_Menu display: none position: absolute - background-color: #fefefe + background-color: var(--nav-bg-color) box-sizing: border-box padding: .5rem + max-width: 250px + right: 0 &_Item margin: .2rem 0 + color: var(--main-color) + + &:hover + color: var(--link-color) + &__User justify-content: flex-end diff --git a/src/pages/Navbar/Navbar.tsx b/src/pages/Navbar/Navbar.tsx index 9329ba3..cd03237 100644 --- a/src/pages/Navbar/Navbar.tsx +++ b/src/pages/Navbar/Navbar.tsx @@ -12,7 +12,7 @@ import LoginModal from "../Modals/LoginModal"; type Props = { setModal: SetModal - logout: () => void + logout: LogoutUser currentUser: UserType }; @@ -63,6 +63,37 @@ class Navbar extends React.Component { ); + const user = isMinimized ? ( +
+
+
+
{this.props.currentUser.username}
+
+
+ Профиль + {currentUser.group && hasAccessToAdminPanel(currentUser) && ( + + Админ-панель + + )} + Настройки +
Выход
+
+
+ ) : (<> + +
+
{this.props.currentUser.username}
+ + {currentUser.group && hasAccessToAdminPanel(currentUser) && ( + + Админ-панель + + )} + Настройки +
Выйти
+ ) + return (