many new
This commit is contained in:
Executable
+107
@@ -0,0 +1,107 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap')
|
||||
@import "../../Constants"
|
||||
|
||||
html, body, #root
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
body, pre, textarea
|
||||
font-family: 'Roboto', sans-serif
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p, body, pre
|
||||
margin: 0
|
||||
|
||||
body
|
||||
padding: 0
|
||||
|
||||
--main-color: #{$mainColor}
|
||||
--sec-color: #{$secondaryColor}
|
||||
--link-color: #{$linkHoverColor}
|
||||
|
||||
--main-bg-color: #{$primaryBackgroundColor}
|
||||
--sec-bg-color: #{$secondaryBackgroundColor}
|
||||
--block-color: #{$blockBackgroundColor}
|
||||
--block-sec-color: #{$blockSecondaryBackgroundColor}
|
||||
--nav-bg-color: #{$navbarBackgroundColor}
|
||||
|
||||
--error-bg-color: #{$errorBackgroundColor}
|
||||
--success-bg-color: #{$successBackgroundColor}
|
||||
|
||||
color: var(--main-color)
|
||||
background: var(--main-bg-color)
|
||||
|
||||
pre
|
||||
white-space: pre-wrap
|
||||
|
||||
body[theme='red']
|
||||
--main-bg-color: #{$primaryBackgroundColorRed}
|
||||
--sec-bg-color: #{$secondaryBackgroundColorRed}
|
||||
--block-color: #{$blockBackgroundColorRed}
|
||||
--block-sec-color: #{$blockSecondaryBackgroundColorRed}
|
||||
--nav-bg-color: #{$navbarBackgroundColorRed}
|
||||
|
||||
body[theme='blue']
|
||||
--main-bg-color: #{$primaryBackgroundColorBlue}
|
||||
--sec-bg-color: #{$secondaryBackgroundColorBlue}
|
||||
--block-color: #{$blockBackgroundColorBlue}
|
||||
--block-sec-color: #{$blockSecondaryBackgroundColorBlue}
|
||||
--nav-bg-color: #{$navbarBackgroundColorBlue}
|
||||
|
||||
body[theme='green']
|
||||
--main-bg-color: #{$primaryBackgroundColorGreen}
|
||||
--sec-bg-color: #{$secondaryBackgroundColorGreen}
|
||||
--block-color: #{$blockBackgroundColorGreen}
|
||||
--block-sec-color: #{$blockSecondaryBackgroundColorGreen}
|
||||
--nav-bg-color: #{$navbarBackgroundColorGreen}
|
||||
|
||||
body[theme='light']
|
||||
--main-color: #{$mainColorLight}
|
||||
--link-color: #{$linkHoverColorLight}
|
||||
--sec-color: #{$secondaryColorLight}
|
||||
|
||||
--main-bg-color: #{$primaryBackgroundColorLight}
|
||||
--sec-bg-color: #{$secondaryBackgroundColorLight}
|
||||
--block-color: #{$blockBackgroundColorLight}
|
||||
--block-sec-color: #{$blockSecondaryBackgroundColorLight}
|
||||
--nav-bg-color: #{$navbarBackgroundColorLight}
|
||||
|
||||
color: var(--main-color)
|
||||
background: var(--main-bg-color)
|
||||
|
||||
a
|
||||
color: var(--main-color)
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
color: var(--link-color)
|
||||
|
||||
*
|
||||
scrollbar-color: #eee #222
|
||||
scrollbar-width: thin
|
||||
|
||||
.Container
|
||||
max-width: 1200px
|
||||
min-height: calc(100vh - 16rem)
|
||||
margin: .5rem auto
|
||||
|
||||
.Notifications
|
||||
position: fixed
|
||||
bottom: 0
|
||||
left: 0
|
||||
z-index: 100000
|
||||
|
||||
@media (min-width: 500px)
|
||||
padding: 1rem
|
||||
box-sizing: border-box
|
||||
|
||||
.Successful, .Error
|
||||
border: var(--link-color) 1px solid
|
||||
padding: .5rem
|
||||
border-radius: 3px
|
||||
margin-bottom: 1rem
|
||||
|
||||
.Error
|
||||
background-color: var(--error-bg-color)
|
||||
|
||||
.Successful
|
||||
background-color: var(--success-bg-color)
|
||||
Executable
+126
@@ -0,0 +1,126 @@
|
||||
import React from 'react';
|
||||
import {Switch, Route} from "react-router-dom";
|
||||
import './App.sass';
|
||||
import Navbar from "../Navbar/Navbar";
|
||||
import Novel from "../Novel/Novel";
|
||||
import User from "../User/User";
|
||||
import Main from "../Main/Main"
|
||||
import NotFoundError from "../NotFoundError";
|
||||
import {fetchCurrentUser} from "../../api/users";
|
||||
import {connect} from "react-redux";
|
||||
import {setUser} from "../../store/actions";
|
||||
import Character from "../Character/Character";
|
||||
// @ts-ignore
|
||||
import parser from 'bbcode-to-react';
|
||||
import SpoilerTag from "../../ui/Spoiler/SpoilerTag";
|
||||
import Novels from "../Novels/Novels";
|
||||
import Footer from '../Footer/Footer';
|
||||
import UserNovels from '../User/Novels/UserNovels';
|
||||
import ColorTag from "../../ui/Tags/ColorTag";
|
||||
import ActivateAccount from "../ActivateAccount";
|
||||
import AllNews from "../News/AllNews";
|
||||
import Post from "../News/Post";
|
||||
import AdminPanel from "../AdminPanel/AdminPanel";
|
||||
import PasswordRestoreGenerate from "../PasswordRestore/PasswordRestoreGenerate";
|
||||
import PasswordRestore from "../PasswordRestore/PasswordRestore";
|
||||
import Users from "../Users/Users";
|
||||
import {getVersion, version} from "../../api/api";
|
||||
import Settings from "../User/Settings/Settings";
|
||||
|
||||
type Props = {
|
||||
notifications: React.ReactNode[]
|
||||
setUser: (user: UserType) => void
|
||||
modal: React.ReactNode
|
||||
};
|
||||
|
||||
type State = {}
|
||||
|
||||
class App extends React.Component<Props, State> {
|
||||
state: State = {}
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
const { setUser } = this.props;
|
||||
fetchCurrentUser().then(setUser).catch((err: ApiError) => {
|
||||
if(err.code !== 3 && err.text) console.error(err.text);
|
||||
});
|
||||
|
||||
const theme = localStorage.getItem('theme');
|
||||
if(theme)
|
||||
document.body.setAttribute('theme', theme);
|
||||
|
||||
parser.registerTag('spoiler', SpoilerTag);
|
||||
parser.registerTag('color', ColorTag);
|
||||
|
||||
getVersion().then(res => {
|
||||
if(version !== res.version) {
|
||||
console.debug(`Current back-end version: ${res.version}. Clearing cache`);
|
||||
|
||||
caches.keys().then(names => {
|
||||
names.forEach(name => caches.delete(name).catch(console.error))
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { modal } = this.props;
|
||||
const notificationWidth = window.screen.width >= 500 ? 500 : window.screen.width;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar/>
|
||||
<div className={'Container'}>
|
||||
<div className="Notifications" style={{ width: notificationWidth }}>
|
||||
{this.props.notifications.map((n, i) => (
|
||||
<React.Fragment key={i}>
|
||||
{n}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
<Switch>
|
||||
<Route exact path={'/'} component={Main}/>
|
||||
|
||||
<Route exact path={'/news'} component={AllNews}/>
|
||||
<Route exact path={'/news/:postId'} component={Post}/>
|
||||
|
||||
<Route exact path={'/novels'} component={Novels}/>
|
||||
<Route exact path={'/novels/:novelId'} component={Novel}/>
|
||||
|
||||
<Route exact path={'/users'} component={Users}/>
|
||||
<Route exact path={'/user/:userId'} component={User}/>
|
||||
<Route exact path={'/user/:userId/novels'} component={UserNovels}/>
|
||||
<Route exact path={'/user/:userId/settings'} component={Settings}/>
|
||||
|
||||
<Route exact path={'/character/:charId'} component={Character}/>
|
||||
|
||||
<Route exact path={'/activate/:token'} component={ActivateAccount}/>
|
||||
|
||||
<Route exact path={'/restore'} component={PasswordRestoreGenerate}/>
|
||||
<Route exact path={'/restore/:token'} component={PasswordRestore}/>
|
||||
|
||||
<Route path={'/kawaii__neko'} component={AdminPanel}/>
|
||||
|
||||
<Route component={NotFoundError}/>
|
||||
</Switch>
|
||||
|
||||
{modal && modal}
|
||||
</div>
|
||||
<Footer/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: StoreState) => ({
|
||||
notifications: state.notifications,
|
||||
modal: state.modal
|
||||
}),
|
||||
dispatch => ({
|
||||
setUser: (userData: UserType) => {
|
||||
dispatch(setUser(userData))
|
||||
}
|
||||
})
|
||||
)(App);
|
||||
Reference in New Issue
Block a user