merge front
commit
d95de20cfd
|
|
@ -0,0 +1,97 @@
|
||||||
|
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.gatsbyjs.org">
|
||||||
|
<img alt="Gatsby" src="https://www.gatsbyjs.org/monogram.svg" width="60" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h1 align="center">
|
||||||
|
Gatsby's default starter
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
Kick off your project with this default boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
|
||||||
|
|
||||||
|
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.org/docs/gatsby-starters/)._
|
||||||
|
|
||||||
|
## 🚀 Quick start
|
||||||
|
|
||||||
|
1. **Create a Gatsby site.**
|
||||||
|
|
||||||
|
Use the Gatsby CLI to create a new site, specifying the default starter.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# create a new Gatsby site using the default starter
|
||||||
|
gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **Start developing.**
|
||||||
|
|
||||||
|
Navigate into your new site’s directory and start it up.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd my-default-starter/
|
||||||
|
gatsby develop
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **Open the source code and start editing!**
|
||||||
|
|
||||||
|
Your site is now running at `http://localhost:8000`!
|
||||||
|
|
||||||
|
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
|
||||||
|
|
||||||
|
Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
|
||||||
|
|
||||||
|
## 🧐 What's inside?
|
||||||
|
|
||||||
|
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
||||||
|
|
||||||
|
.
|
||||||
|
├── node_modules
|
||||||
|
├── src
|
||||||
|
├── .gitignore
|
||||||
|
├── .prettierrc
|
||||||
|
├── gatsby-browser.js
|
||||||
|
├── gatsby-config.js
|
||||||
|
├── gatsby-node.js
|
||||||
|
├── gatsby-ssr.js
|
||||||
|
├── LICENSE
|
||||||
|
├── package-lock.json
|
||||||
|
├── package.json
|
||||||
|
└── README.md
|
||||||
|
|
||||||
|
1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
|
||||||
|
|
||||||
|
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
|
||||||
|
|
||||||
|
3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
|
||||||
|
|
||||||
|
4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent.
|
||||||
|
|
||||||
|
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
|
||||||
|
|
||||||
|
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you’d like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
|
||||||
|
|
||||||
|
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
|
||||||
|
|
||||||
|
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
||||||
|
|
||||||
|
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
|
||||||
|
|
||||||
|
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won’t change this file directly).**
|
||||||
|
|
||||||
|
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project’s name, author, etc). This manifest is how npm knows which packages to install for your project.
|
||||||
|
|
||||||
|
12. **`README.md`**: A text file containing useful reference information about your project.
|
||||||
|
|
||||||
|
## 🎓 Learning Gatsby
|
||||||
|
|
||||||
|
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
|
||||||
|
|
||||||
|
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
|
||||||
|
|
||||||
|
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
|
||||||
|
|
||||||
|
## 💫 Deploy
|
||||||
|
|
||||||
|
[](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default)
|
||||||
|
|
||||||
|
<!-- AUTO-GENERATED-CONTENT:END -->
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
sudo sysctl fs.inotify.max_user_watches=524288
|
||||||
|
gatsby clean
|
||||||
|
gatsby develop
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { chatOnOpen, chatOnClose, getChatRooms } from '../../stores/chat/duck/operations'
|
||||||
|
|
||||||
|
import '../../styles/indexChat.scss'
|
||||||
|
|
||||||
|
const ChatConnect = ({ chat, chatOnOpen, chatOnClose, getChatRooms }) => {
|
||||||
|
|
||||||
|
const inputLobbyName = React.createRef()
|
||||||
|
|
||||||
|
const setLobbyName = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if ( inputLobbyName.current.value !== '' ){
|
||||||
|
chatOnOpen(inputLobbyName.current.value)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inputLobbyName.current.value = 'Get a lobby name!'
|
||||||
|
}
|
||||||
|
|
||||||
|
const disconnect = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
try{
|
||||||
|
chat.webSocket.close()
|
||||||
|
chatOnClose()
|
||||||
|
getChatRooms()
|
||||||
|
}catch {
|
||||||
|
chatOnClose()
|
||||||
|
getChatRooms()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chat.connected === false)
|
||||||
|
return (
|
||||||
|
<form onSubmit={ setLobbyName }>
|
||||||
|
<input
|
||||||
|
placeholder='lobby / room name'
|
||||||
|
ref={ inputLobbyName } />
|
||||||
|
<button >
|
||||||
|
Connect
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
else
|
||||||
|
return (
|
||||||
|
<form onSubmit={ disconnect }>
|
||||||
|
<div className='lobbyName'>
|
||||||
|
Lobby: { chat.lobby }
|
||||||
|
</div>
|
||||||
|
<button >
|
||||||
|
Disconnect
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
chat: state.chat
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
chatOnOpen: chat => dispatch( chatOnOpen(chat) ),
|
||||||
|
chatOnClose: chat => dispatch( chatOnClose(chat) ),
|
||||||
|
getChatRooms: chat => dispatch( getChatRooms(chat) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ChatConnect)
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { chatOnMessage, getChatRooms } from '../../stores/chat/duck/operations'
|
||||||
|
|
||||||
|
import ChatConnect from './chatConnect'
|
||||||
|
|
||||||
|
import '../../styles/indexChat.scss'
|
||||||
|
|
||||||
|
import imageIco from '../../images/imageIco.png'
|
||||||
|
|
||||||
|
const IndexChat = ({ user, chat, chatOnMessage, getChatRooms }) => {
|
||||||
|
|
||||||
|
const [chatVisible, setChatVisible] = useState(false)
|
||||||
|
const [chatImageVisible, setChatImageVisible] = useState( { visible: false, image: ''} )
|
||||||
|
|
||||||
|
const inputMessageText = React.createRef()
|
||||||
|
|
||||||
|
useEffect( () => { getChatRooms() }, [] )
|
||||||
|
|
||||||
|
if ( chat.host !== '' )
|
||||||
|
chat.webSocket.onmessage = (event) => {
|
||||||
|
chatOnMessage(JSON.parse(event.data))
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendMessage = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
let checkUploadValue = document.getElementById('fileItem').value
|
||||||
|
|
||||||
|
if ( inputMessageText.current.value !== '' && checkUploadValue !== '' && chat.host !== '' ) {
|
||||||
|
|
||||||
|
let inputMessageImage = document.getElementById('fileItem').files[0]
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
userID: user.id,
|
||||||
|
userName: user.login,
|
||||||
|
avatar: user.avatar,
|
||||||
|
text: inputMessageText.current.value,
|
||||||
|
textOnly: false,
|
||||||
|
imageOnly: false
|
||||||
|
}
|
||||||
|
inputMessageText.current.value = ''
|
||||||
|
document.getElementById('fileItem').value = ''
|
||||||
|
sendBase64Image(inputMessageImage, message)
|
||||||
|
}
|
||||||
|
else if (inputMessageText.current.value !== '' && chat.host !== '' ) {
|
||||||
|
let message = {
|
||||||
|
userID: user.id,
|
||||||
|
userName: user.login,
|
||||||
|
avatar: user.avatar,
|
||||||
|
text: inputMessageText.current.value,
|
||||||
|
textOnly: true,
|
||||||
|
imageOnly: false
|
||||||
|
}
|
||||||
|
inputMessageText.current.value = ''
|
||||||
|
chat.webSocket.send(JSON.stringify(message))
|
||||||
|
}
|
||||||
|
else if ( checkUploadValue !== '' ) {
|
||||||
|
let inputMessageImage = document.getElementById('fileItem').files[0]
|
||||||
|
let message = {
|
||||||
|
userID: user.id,
|
||||||
|
userName: user.login,
|
||||||
|
avatar: user.avatar,
|
||||||
|
textOnly: false,
|
||||||
|
imageOnly: true
|
||||||
|
}
|
||||||
|
document.getElementById('fileItem').value = ''
|
||||||
|
sendBase64Image(inputMessageImage, message)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inputMessageText.current.value = 'Type message'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendBase64Image = (image, message) => {
|
||||||
|
let reader = new FileReader()
|
||||||
|
reader.onload = () => {
|
||||||
|
message.image = reader.result
|
||||||
|
chat.webSocket.send(JSON.stringify(message))
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(image)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ chatVisible === true ? (chat.host !== '' ? 'chatWindowOpen' : 'chatWindowChangeLobby') : 'chatWindowHide'}>
|
||||||
|
<div
|
||||||
|
className='chatMenuBar'
|
||||||
|
onClick={ () => setChatVisible( !chatVisible ) }>
|
||||||
|
chat
|
||||||
|
</div>
|
||||||
|
<div className='chatBody'>
|
||||||
|
<div className='lobbyMessage'>
|
||||||
|
<ChatConnect/>
|
||||||
|
</div>
|
||||||
|
<div className='listMessage'>
|
||||||
|
{ chat.host !== '' ? chat.messages.map( (message, key) => {
|
||||||
|
if ( chatImageVisible.visible )
|
||||||
|
return (
|
||||||
|
<div className='imageFullStyle' onClick={ () => setChatImageVisible( { visible: !chatImageVisible.visible, image: '' } ) }>
|
||||||
|
<img src={ chatImageVisible.image } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
if (message.userID === -1)
|
||||||
|
return (
|
||||||
|
<div></div>
|
||||||
|
)
|
||||||
|
else if (message.userID === user.id)
|
||||||
|
return (
|
||||||
|
<div className='rowMessage' key={key}>
|
||||||
|
<div className="chatAvatar">
|
||||||
|
<img src={message.avatar} title={message.userName} />
|
||||||
|
</div>
|
||||||
|
<div className='chatMessageDisplay' onClick={ message.textOnly !== true ? () => setChatImageVisible( { visible: !chatImageVisible.visible, image: message.image } ) : () => {} }>
|
||||||
|
{ message.imageOnly === false ?
|
||||||
|
<div className={ message.imageOnly !== message.textOnly ? 'userMessage': 'userMessage messageWithImage' }>
|
||||||
|
{message.text}
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div></div>
|
||||||
|
}
|
||||||
|
{ message.textOnly === false ? <img src={message.image} /> : <div></div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else
|
||||||
|
return (
|
||||||
|
<div className='rowMessage' key={key}>
|
||||||
|
<div className="chatAvatar">
|
||||||
|
<img src={message.avatar} title={message.userName} />
|
||||||
|
</div>
|
||||||
|
<div className='chatMessageDisplay' onClick={ message.textOnly !== true ? () => setChatImageVisible( { visible: !chatImageVisible.visible, image: message.image } ) : () => {} }>
|
||||||
|
{ message.imageOnly === false ?
|
||||||
|
<div className={ message.imageOnly !== message.textOnly ? 'otherMessage': 'otherMessage messageWithImage' }>
|
||||||
|
{message.text}
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div></div>
|
||||||
|
}
|
||||||
|
{ message.textOnly === false ? <img src={message.image} /> : <div></div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
: ( chat.rooms.lenght === 0 ?
|
||||||
|
() => {
|
||||||
|
return (
|
||||||
|
<div className='chatListItem'>
|
||||||
|
Create first lobby!
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
:
|
||||||
|
chat.rooms.map( (room, key) => {
|
||||||
|
return (
|
||||||
|
<div key={ key } className='chatListItem'>
|
||||||
|
{ key + 1 }. Lobby: { room.name }, Users: { room.userCount }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className='textMessage'>
|
||||||
|
<form onSubmit={ sendMessage }>
|
||||||
|
<input
|
||||||
|
className='inputFile'
|
||||||
|
type='file'
|
||||||
|
id='fileItem' />
|
||||||
|
<img
|
||||||
|
className='inputFile'
|
||||||
|
src={ imageIco } />
|
||||||
|
<input
|
||||||
|
placeholder='message'
|
||||||
|
ref={ inputMessageText } />
|
||||||
|
<button>
|
||||||
|
Send
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
user: state.user,
|
||||||
|
chat: state.chat
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
chatOnMessage: chat => dispatch( chatOnMessage(chat) ),
|
||||||
|
getChatRooms: chat => dispatch( getChatRooms(chat) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(IndexChat)
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { deleteNotification, getUserNotifications } from '../../stores/exchange/duck/operations'
|
||||||
|
|
||||||
|
import '../../styles/indexExchange.scss'
|
||||||
|
|
||||||
|
const ExchangeNotifications = ({
|
||||||
|
user,
|
||||||
|
exchange, deleteNotification, getUserNotifications }) => {
|
||||||
|
|
||||||
|
useEffect( () => { getUserNotifications(user.id) }, [] )
|
||||||
|
|
||||||
|
const deleteOldNotification = (notifyID) => {
|
||||||
|
let notify = {
|
||||||
|
id: notifyID,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
deleteNotification(notify)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='exchangeNotificationsDiv'>
|
||||||
|
<p>{ user.login } exchange notifications:</p>
|
||||||
|
<div className='notifyList'>
|
||||||
|
{ exchange.userNotifications
|
||||||
|
.sort( (a, b) => b.id - a.id )
|
||||||
|
.map( (notify, key) => {
|
||||||
|
return (
|
||||||
|
<div key={ key + 1 }>
|
||||||
|
<p>{ key + 1 }. { notify.message }</p>
|
||||||
|
<button
|
||||||
|
className='deleteButton'
|
||||||
|
onClick={ () => deleteOldNotification(notify.id) }>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
user: state.user,
|
||||||
|
exchange: state.exchange
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
getUserNotifications: exchange => dispatch( getUserNotifications(exchange) ),
|
||||||
|
deleteNotification: exchange => dispatch( deleteNotification(exchange) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps,mapDispatchToProps)(ExchangeNotifications)
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { checkPrognosis } from '../../stores/exchange/duck/operations'
|
||||||
|
|
||||||
|
import '../../styles/indexExchange.scss'
|
||||||
|
|
||||||
|
const ExchangePrognosis = ({
|
||||||
|
user,
|
||||||
|
exchange, checkPrognosis }) => {
|
||||||
|
|
||||||
|
const inputPrognosis = React.createRef()
|
||||||
|
|
||||||
|
const checkNewPrognosis = () => {
|
||||||
|
if ( inputPrognosis.current.value > 0 ) {
|
||||||
|
let prognosis = {
|
||||||
|
price: inputPrognosis.current.value,
|
||||||
|
}
|
||||||
|
checkPrognosis( prognosis )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='exchangePrognosisDiv'>
|
||||||
|
<input
|
||||||
|
placeholder='Write the amount to exchange forecast'
|
||||||
|
onChange={ () => checkNewPrognosis() }
|
||||||
|
ref={ inputPrognosis }>
|
||||||
|
</input>
|
||||||
|
<p>Forecast: { Number((exchange.prognosis.price_forecast).toFixed(2)) } PLN</p>
|
||||||
|
<p>Percent: { Number((exchange.prognosis.percent_of_difference).toFixed(3)) } %</p>
|
||||||
|
<p>Course on payment: { exchange.prognosis.course_on_payment } PLN</p>
|
||||||
|
<p>AVG: { Number((exchange.prognosis.svg_of_all).toFixed(2)) }</p>
|
||||||
|
<p>Date: { exchange.prognosis.date_of_transaction }</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
user: state.user,
|
||||||
|
exchange: state.exchange
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
checkPrognosis: exchange => dispatch( checkPrognosis(exchange) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps,mapDispatchToProps)(ExchangePrognosis)
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { getChart, getUserTriggers, getUserNotifications, getUserTransactions, addTrigger } from '../../stores/exchange/duck/operations'
|
||||||
|
|
||||||
|
import '../../styles/indexExchange.scss'
|
||||||
|
|
||||||
|
const ExchangeTriggerAdd = ({
|
||||||
|
user,
|
||||||
|
exchange, getChart, getUserTriggers, getUserNotifications, getUserTransactions, addTrigger,
|
||||||
|
triggerValue }) => {
|
||||||
|
|
||||||
|
useEffect( () => { getUserTriggers(user.id) }, [] )
|
||||||
|
|
||||||
|
const [inputValue, setInputValue] = useState( triggerValue )
|
||||||
|
const [message, setMessage] = useState('')
|
||||||
|
|
||||||
|
const triggerValueAdd = React.createRef()
|
||||||
|
|
||||||
|
const addNewTrigger = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if ( triggerValue !== 0 ) {
|
||||||
|
let newTrigger = {
|
||||||
|
user_id: user.id,
|
||||||
|
course_values_for_trigger: triggerValue,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
addTrigger( newTrigger )
|
||||||
|
setMessage('Trigger has been added')
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setMessage('Trigger add error')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='exchangeTriggerDiv'>
|
||||||
|
<form onSubmit={ addNewTrigger }>
|
||||||
|
<p>Trigger value: { triggerValue } zł</p>
|
||||||
|
<button>
|
||||||
|
Add Trigger
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<p>{ user.login } triggers:</p>
|
||||||
|
<p>{ message }</p>
|
||||||
|
<div className='triggerItemList'>
|
||||||
|
{ exchange.userTriggers
|
||||||
|
.sort( (a, b) => b.id - a.id )
|
||||||
|
.map( (trigger, key) => (
|
||||||
|
<div key={ key + 1 } className='triggerItem'>
|
||||||
|
<p>{ key + 1 }. Value: { trigger.course_values_for_trigger } PLN, Date: { trigger.date_of_trigger }, Status { trigger.status === 1 ? 'Enabled' : 'Disabled' }</p>
|
||||||
|
</div>
|
||||||
|
) ) }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
user: state.user,
|
||||||
|
exchange: state.exchange
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
getUserTriggers: exchange => dispatch( getUserTriggers(exchange) ),
|
||||||
|
addTrigger: exchange => dispatch( addTrigger(exchange) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps,mapDispatchToProps)(ExchangeTriggerAdd)
|
||||||
|
|
@ -1,19 +1,177 @@
|
||||||
import React from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import '../../styles/index.scss'
|
import { getChart, getUserTriggers, getUserNotifications, getUserTransactions } from '../../stores/exchange/duck/operations'
|
||||||
|
|
||||||
const IndexExchange = ({ user }) => {
|
import { useInterval } from '../useInterval'
|
||||||
|
|
||||||
|
import ExchangeTriggerAdd from './exchangeTriggerAdd'
|
||||||
|
import ExchangePrognosis from './exchangePrognosis'
|
||||||
|
import ExchangeNotifications from './exchangeNotifications'
|
||||||
|
|
||||||
|
import '../../styles/indexExchange.scss'
|
||||||
|
|
||||||
|
const IndexExchange = ({
|
||||||
|
user,
|
||||||
|
exchange, getChart, getUserTriggers, getUserNotifications, getUserTransactions }) => {
|
||||||
|
|
||||||
|
let fifteenMinuts = 1500000
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
getChart()
|
||||||
|
}, fifteenMinuts)
|
||||||
|
|
||||||
|
const [candleInfo, setCandleInfo] = useState({ Open: 0, Close: 0, Min: 0, Max: 0, Vol: 0 })
|
||||||
|
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
|
||||||
|
const [triggerValue, setTriggerValue] = useState(0)
|
||||||
|
|
||||||
|
const colorGreen = {
|
||||||
|
background: 'green'//'rgba(0,93,0,1)',
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorRed = {
|
||||||
|
background: 'red'//'rgba(136,15,15,1)',
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCandleInformation = (candle) => {
|
||||||
|
setCandleInfo({
|
||||||
|
Open: candle.Open,
|
||||||
|
Close: candle.Close,
|
||||||
|
Min: candle.Min,
|
||||||
|
Max: candle.Max,
|
||||||
|
Vol: candle.Volume,
|
||||||
|
Date: candle.Date
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let pixelScale = (exchange.candles.graphMax - exchange.candles.graphMin) / 590
|
||||||
|
let cursorValue = exchange.candles.graphMax - (pixelScale * (mousePosition.y - 175))
|
||||||
|
|
||||||
|
const getMousePosition = (event) => {
|
||||||
|
setMousePosition({ x: event.pageX, y: event.pageY })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect( () => responsiveIntrface())
|
||||||
|
|
||||||
|
const responsiveIntrface = () => {
|
||||||
|
if ( user.id != -1) {
|
||||||
|
let chartHeight = 600
|
||||||
|
let chartPaddingTop = 175
|
||||||
|
let exchangeInterfaceHeight = window.innerHeight - (chartHeight + chartPaddingTop)
|
||||||
|
document.getElementById('exchangeInterfaceTwo').style = 'height: ' + exchangeInterfaceHeight + 'px;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='indexExchange'>
|
||||||
|
<div className={user.id > -1 ? 'exchangeChartUser' : 'exchangeChartGuest'}>
|
||||||
|
<div className='chart'
|
||||||
|
onMouseOver={event => getMousePosition(event)}
|
||||||
|
onClick={() => setTriggerValue(parseInt(cursorValue))}
|
||||||
|
style={{ width: exchange.candles.candlesCount * 15 + 'px' }}>
|
||||||
|
{user.id > -1 ? (
|
||||||
|
<div>
|
||||||
|
<div className='exchangeTriggerDativeY'
|
||||||
|
style={{ transform: 'translateY(' + (mousePosition.y - 175) + 'px)' }}>
|
||||||
|
<p>{parseInt(cursorValue)} PLN</p>
|
||||||
|
</div>
|
||||||
|
<div className='exchangeTriggerDativeX'
|
||||||
|
style={{ transform: 'translateX(' + (mousePosition.x) + 'px)' }}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
)}
|
||||||
|
{exchange.candles.candles.map((candle, key) => {
|
||||||
|
|
||||||
|
const color = candle.Open > candle.Close ? colorRed.background : colorGreen.background
|
||||||
|
|
||||||
|
let highValue = candle.Open > candle.Close ? candle.Open : candle.Close
|
||||||
|
let lowValue = candle.Open < candle.Close ? candle.Open : candle.Close
|
||||||
|
|
||||||
|
let scaleProperties = 10
|
||||||
|
|
||||||
|
let chartScaleY = (exchange.candles.graphMax - candle.Max) / pixelScale
|
||||||
|
|
||||||
|
let onePercentScaleY = 100 / chartScaleY
|
||||||
|
let difference = (highValue - lowValue) / pixelScale
|
||||||
|
|
||||||
|
if (parseInt(difference) === 0)
|
||||||
|
difference = 1
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={key}
|
||||||
|
className='sectionChart'
|
||||||
|
onMouseOver={() => getCandleInformation(candle)}>
|
||||||
|
|
||||||
|
<div className='sectionCandle'>
|
||||||
|
<div
|
||||||
|
className='candle'
|
||||||
|
style={{ paddingTop: chartScaleY + 'px' }}>
|
||||||
|
<div
|
||||||
|
className='candleMaxValue'
|
||||||
|
style={{ height: parseInt((candle.Max - highValue) / pixelScale) + 'px', background: color }}>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='candleHigh'
|
||||||
|
style={{ height: parseInt(difference) + 'px', background: color }}>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='candleMinValue'
|
||||||
|
style={{ height: parseInt((lowValue - candle.Min) / pixelScale) + 'px', background: color }}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='sectionVolumen'>
|
||||||
|
<div className='volumen'
|
||||||
|
style={{ height: candle.Volume / 1.5 + 'px' }}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={user.id > -1 ? 'exchangeInterface' : 'exchangeEmptySpace'}>
|
||||||
|
<div className='candleInformation'>
|
||||||
|
<p>Open: {candleInfo.Open} PLN</p>
|
||||||
|
<p>Close: {candleInfo.Close} PLN</p>
|
||||||
|
<p>Max: {candleInfo.Max} PLN</p>
|
||||||
|
<p>Min: {candleInfo.Min} PLN</p>
|
||||||
|
<p>Volume: {candleInfo.Vol}</p>
|
||||||
|
<p>Date: {candleInfo.Date}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{user.id > -1 ? (
|
||||||
|
<div id='exchangeInterfaceTwo'>
|
||||||
|
<ExchangeTriggerAdd triggerValue={triggerValue} />
|
||||||
|
<ExchangePrognosis />
|
||||||
|
<ExchangeNotifications />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
user: state.user,
|
user: state.user,
|
||||||
|
exchange: state.exchange
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
getChart: exchange => dispatch(getChart(exchange)),
|
||||||
|
getUserTriggers: exchange => dispatch(getUserTriggers(exchange)),
|
||||||
|
getUserNotifications: exchange => dispatch(getUserNotifications(exchange)),
|
||||||
|
getUserTransactions: exchange => dispatch(getUserTransactions(exchange))
|
||||||
|
})
|
||||||
|
|
||||||
export default connect(mapStateToProps,null)(IndexExchange)
|
export default connect(mapStateToProps, mapDispatchToProps)(IndexExchange)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,15 @@ const ForumCommentUpdate = ({
|
||||||
|
|
||||||
const updateCommentTextArea = React.createRef()
|
const updateCommentTextArea = React.createRef()
|
||||||
|
|
||||||
const updateOldComment = (event) => {
|
const sleep = (ms) => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
|
}
|
||||||
|
|
||||||
|
let subjectLoad = {
|
||||||
|
id: subjects.actualSubjectID
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateOldComment = async (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if ( updateCommentTextArea.current.value !== '' ) {
|
if ( updateCommentTextArea.current.value !== '' ) {
|
||||||
let commentData = {
|
let commentData = {
|
||||||
|
|
@ -25,7 +33,9 @@ const ForumCommentUpdate = ({
|
||||||
text: updateCommentTextArea.current.value
|
text: updateCommentTextArea.current.value
|
||||||
}
|
}
|
||||||
updateCommentTextArea.current.value = ''
|
updateCommentTextArea.current.value = ''
|
||||||
updateComment(commentData)
|
await updateComment(commentData)
|
||||||
|
await sleep(100)
|
||||||
|
await refreshSubjectComments(subjectLoad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,16 @@ const ForumComments = ({
|
||||||
const [formDiv, setFormDiv] = useState(false)
|
const [formDiv, setFormDiv] = useState(false)
|
||||||
|
|
||||||
const addCommentTextArea = React.createRef()
|
const addCommentTextArea = React.createRef()
|
||||||
const updateCommentTextArea = React.createRef()
|
|
||||||
|
|
||||||
const addNewComment = (event) => {
|
let subjectLoad = {
|
||||||
|
id: subjects.actualSubjectID
|
||||||
|
}
|
||||||
|
|
||||||
|
const sleep = (ms) => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
|
}
|
||||||
|
|
||||||
|
const addNewComment = async (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if ( addCommentTextArea.current.value !== '' ) {
|
if ( addCommentTextArea.current.value !== '' ) {
|
||||||
let newComment = {
|
let newComment = {
|
||||||
|
|
@ -34,25 +41,21 @@ const ForumComments = ({
|
||||||
token: user.token
|
token: user.token
|
||||||
}
|
}
|
||||||
addCommentTextArea.current.value = ''
|
addCommentTextArea.current.value = ''
|
||||||
addComment(newComment)
|
await addComment( newComment )
|
||||||
|
await sleep(100)
|
||||||
|
await refreshSubjectComments(subjectLoad)
|
||||||
setFormDiv( !formDiv )
|
setFormDiv( !formDiv )
|
||||||
let actualSubject = {
|
|
||||||
id: subjects.actualSubjectID
|
|
||||||
}
|
|
||||||
refreshSubjectComments(actualSubject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteOldComment = (commentID) => {
|
const deleteOldComment = async(commentID) => {
|
||||||
let delComment = {
|
let delComment = {
|
||||||
id: commentID,
|
id: commentID,
|
||||||
token: user.token
|
token: user.token
|
||||||
}
|
}
|
||||||
deleteComment(delComment)
|
await deleteComment(delComment)
|
||||||
let actualSubject = {
|
await sleep(100)
|
||||||
id: subjects.actualSubjectID
|
await refreshSubjectComments(subjectLoad)
|
||||||
}
|
|
||||||
refreshSubjectComments(actualSubject)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const [commentText, setCommentText] = useState(0)
|
const [commentText, setCommentText] = useState(0)
|
||||||
|
|
|
||||||
|
|
@ -57,21 +57,22 @@ const ForumRatings = ({
|
||||||
let divYPositionOnPage = ratingDiv.getBoundingClientRect().top + 72
|
let divYPositionOnPage = ratingDiv.getBoundingClientRect().top + 72
|
||||||
let yPosition = event.screenY - divYPositionOnPage
|
let yPosition = event.screenY - divYPositionOnPage
|
||||||
|
|
||||||
if ( yPosition > 200 ) {
|
if ( yPosition > 270 ) {
|
||||||
setValue(5)
|
setValue(5)
|
||||||
}
|
}
|
||||||
else if ( yPosition > 150 && yPosition < 200 ) {
|
else if ( yPosition > 215 && yPosition < 270 ) {
|
||||||
setValue(4)
|
setValue(4)
|
||||||
}
|
}
|
||||||
else if ( yPosition > 100 && yPosition < 150 ) {
|
else if ( yPosition > 168 && yPosition < 215 ) {
|
||||||
setValue(3)
|
setValue(3)
|
||||||
}
|
}
|
||||||
else if ( yPosition > 50 && yPosition < 150 ) {
|
else if ( yPosition > 120 && yPosition < 168 ) {
|
||||||
setValue(2)
|
setValue(2)
|
||||||
}
|
}
|
||||||
else if ( yPosition > 0 && yPosition < 50 ) {
|
else if ( yPosition > 60 && yPosition < 120 ) {
|
||||||
setValue(1)
|
setValue(1)
|
||||||
}
|
}
|
||||||
|
console.log(yPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
const [updateRating, setUpdate] = useState(false)
|
const [updateRating, setUpdate] = useState(false)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const ForumSubjectUpdate = ({
|
||||||
const updateSubjectTitle = React.createRef()
|
const updateSubjectTitle = React.createRef()
|
||||||
const updateSubjectAuthor = React.createRef()
|
const updateSubjectAuthor = React.createRef()
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
const updateOldSubject = (event) => {
|
const updateOldSubject = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if ( updateSubjectTitle.current.value !== '') {
|
if ( updateSubjectTitle.current.value !== '') {
|
||||||
|
|
@ -25,6 +26,29 @@ const ForumSubjectUpdate = ({
|
||||||
name: updateSubjectTitle.current.value,
|
name: updateSubjectTitle.current.value,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
thread_id: threads.actualThreadID,
|
thread_id: threads.actualThreadID,
|
||||||
|
=======
|
||||||
|
const [selectAuthorID, setSelectAuthorID] = useState(-1)
|
||||||
|
const [selectThreadID, setSelectThreadID] = useState(-1)
|
||||||
|
|
||||||
|
const updateOldSubject = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if ( updateSubjectTitle.current.value !== '' && selectAuthorID === -1 && selectThreadID === -1 ) {
|
||||||
|
let putSubject = {
|
||||||
|
id: subject.id,
|
||||||
|
name: updateSubjectTitle.current.value,
|
||||||
|
user_id: subject.user_id,
|
||||||
|
thread_id: subject.thread_id,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
updateSubject(putSubject)
|
||||||
|
updateSubjectTitle.current.value = ''
|
||||||
|
} else if ( updateSubjectTitle.current.value !== '' && user.privilige >= 2 ) {
|
||||||
|
let putSubject = {
|
||||||
|
id: subject.id,
|
||||||
|
name: updateSubjectTitle.current.value,
|
||||||
|
user_id: selectAuthorID === -1 ? subject.user_id : selectAuthorID,
|
||||||
|
thread_id: selectThreadID === -1 ? subject.thread_id : selectThreadID,
|
||||||
|
>>>>>>> front
|
||||||
token: user.token
|
token: user.token
|
||||||
}
|
}
|
||||||
updateSubject(putSubject)
|
updateSubject(putSubject)
|
||||||
|
|
@ -51,8 +75,13 @@ const ForumSubjectUpdate = ({
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name='updateSubjectAuthorText'
|
name='updateSubjectAuthorText'
|
||||||
|
<<<<<<< HEAD
|
||||||
value={ user.allUsersList }
|
value={ user.allUsersList }
|
||||||
ref={ updateSubjectAuthor }>
|
ref={ updateSubjectAuthor }>
|
||||||
|
=======
|
||||||
|
onChange={ e => setSelectAuthorID( e.target.value ) }>
|
||||||
|
<option value={ subject.user_id }>Choice Author ( actual: { subject.author } )</option>
|
||||||
|
>>>>>>> front
|
||||||
{ user.allUsersList.map( userObject =>
|
{ user.allUsersList.map( userObject =>
|
||||||
<option value={userObject.id}>{userObject.login}, Privilige: { userObject.privilige >= 2 ? 'Moderator' : 'Normal User' }</option>
|
<option value={userObject.id}>{userObject.login}, Privilige: { userObject.privilige >= 2 ? 'Moderator' : 'Normal User' }</option>
|
||||||
)
|
)
|
||||||
|
|
@ -60,7 +89,12 @@ const ForumSubjectUpdate = ({
|
||||||
</select>
|
</select>
|
||||||
<select
|
<select
|
||||||
name='updateSubjectAuthorText'
|
name='updateSubjectAuthorText'
|
||||||
|
<<<<<<< HEAD
|
||||||
value={ threads.threadsList }>
|
value={ threads.threadsList }>
|
||||||
|
=======
|
||||||
|
onChange={ e => setSelectThreadID( e.target.value ) }>
|
||||||
|
<option value={ threads.actualThreadID }>Choice Thread ( actual: { threads.actualThreadName } )</option>
|
||||||
|
>>>>>>> front
|
||||||
{ threads.threadsList.map( threadObject =>
|
{ threads.threadsList.map( threadObject =>
|
||||||
<option value={threadObject.id}>{threadObject.name}, moderator: {threadObject.moderator}</option>
|
<option value={threadObject.id}>{threadObject.name}, moderator: {threadObject.moderator}</option>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useState } from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import { refreshThreadSubjects } from '../../stores/threads/duck/operations'
|
import { refreshThreadSubjects } from '../../stores/threads/duck/operations'
|
||||||
import { getSubjectComments, addSubject } from '../../stores/subjects/duck/operations'
|
import { getSubjectComments, addSubject, deleteSubject } from '../../stores/subjects/duck/operations'
|
||||||
import { addComment } from '../../stores/comments/duck/operations'
|
import { addComment } from '../../stores/comments/duck/operations'
|
||||||
import actions from '../../stores/threads/duck/actions'
|
import actions from '../../stores/threads/duck/actions'
|
||||||
|
|
||||||
|
|
@ -14,14 +14,16 @@ import ForumSubjectUpdate from './forumSubjectUpdate'
|
||||||
const ForumSubjects = ({
|
const ForumSubjects = ({
|
||||||
user,
|
user,
|
||||||
threads, deactivate,
|
threads, deactivate,
|
||||||
subjects, addSubject, getSubjectComments,
|
subjects, addSubject, deleteSubject, getSubjectComments,
|
||||||
comments, addComment }) => {
|
comments, addComment }) => {
|
||||||
|
|
||||||
const [formDiv, setFormDiv] = useState(false)
|
const [formDiv, setFormDiv] = useState(false)
|
||||||
|
const [updateFormDiv, setUpdateFormDiv] = useState( { isActive: false, subject_id: -1 } )
|
||||||
|
|
||||||
const addSubjectTitle = React.createRef()
|
const addSubjectTitle = React.createRef()
|
||||||
const addSubjectComment = React.createRef()
|
const addSubjectComment = React.createRef()
|
||||||
|
|
||||||
|
|
||||||
const addNewSubject = (event) => {
|
const addNewSubject = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if ( addSubjectTitle.current.value !== '' && addSubjectComment.current.value !== '' ) {
|
if ( addSubjectTitle.current.value !== '' && addSubjectComment.current.value !== '' ) {
|
||||||
|
|
@ -42,6 +44,16 @@ const ForumSubjects = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteOldSubject = (subject) => {
|
||||||
|
if( user.id === subject.user_id || user.id === threads.actualThreadModeratorID || user.privilige === 3 ) {
|
||||||
|
let delSubject = {
|
||||||
|
token: user.token,
|
||||||
|
subject_id: subject.id
|
||||||
|
}
|
||||||
|
deleteSubject(delSubject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const [commentText, setCommentText] = useState(0)
|
const [commentText, setCommentText] = useState(0)
|
||||||
const [titleText, setTitleText] = useState(0)
|
const [titleText, setTitleText] = useState(0)
|
||||||
|
|
||||||
|
|
@ -61,36 +73,36 @@ const ForumSubjects = ({
|
||||||
<div className='forumItemsList'>
|
<div className='forumItemsList'>
|
||||||
{ threads.subjectsList.map( subject =>
|
{ threads.subjectsList.map( subject =>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className={subject.author_privilige === 3 ? 'forumListItem adminDivColor' :
|
className={subject.author_privilige === 3 ? 'forumListItem adminDivColor' :
|
||||||
(subject.author_privilige === 2 ? 'forumListItem moderDivColor' : 'forumListItem') }
|
(subject.author_privilige === 2 ? 'forumListItem moderDivColor' : 'forumListItem') }
|
||||||
key={subject.id}>
|
key={subject.id}>
|
||||||
<p onClick={ () => getSubjectComments(subject) }>
|
<p onClick={ () => getSubjectComments(subject) }>
|
||||||
{subject.name}
|
{subject.name}
|
||||||
</p>
|
</p>
|
||||||
<div></div>
|
<div></div>
|
||||||
{ (user.id === subject.user_id ||
|
{ (user.id === subject.user_id ||
|
||||||
user.id === threads.actualThreadModeratorID ||
|
user.id === threads.actualThreadModeratorID ||
|
||||||
user.privilige === 3) ? (
|
user.privilige === 3) ? (
|
||||||
<div>
|
<div>
|
||||||
<button onClick={ () => setSubjectEdit( { isActive: !subjectEdit.isActive, subject_id: subject.id } ) }>
|
<button onClick={ () => setUpdateFormDiv( { isActive: !updateFormDiv.isActive, subject_id: subject.id } )}>
|
||||||
{ subjectEdit.isActive === true ? 'Close Edit' : 'Edit Subject' }
|
{ updateFormDiv.isActive ? 'Close Edit' : 'Edit Subject' }
|
||||||
</button>
|
</button>
|
||||||
<button>
|
<button onClick={ () => deleteOldSubject(subject) }>
|
||||||
Delete Subject
|
Delete Subject
|
||||||
</button>
|
</button>
|
||||||
<img src={subject.author_avatar} />
|
<img src={subject.author_avatar} />
|
||||||
<p>{subject.author}</p>
|
<p>{subject.author}</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<img src={subject.author_avatar} />
|
<img src={subject.author_avatar} />
|
||||||
<p>{subject.author}</p>
|
<p>{subject.author}</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<ForumSubjectUpdate subject={subject} thisSubject={subjectEdit} />
|
<ForumSubjectUpdate subject={subject} thisSubject={updateFormDiv} />
|
||||||
</div>
|
</div>
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -119,9 +131,9 @@ const ForumSubjects = ({
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div className='forumFoot'>
|
<div className='forumFoot'>
|
||||||
<button onClick={ () => setFormDiv( !formDiv ) }>
|
<button onClick={ () => setFormDiv( !formDiv ) }>
|
||||||
{ formDiv === true ? 'Close Add Subject' : 'Add Subject' }
|
{ formDiv === true ? 'Close Add Subject' : 'Add Subject' }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -146,6 +158,7 @@ const mapDispatchToProps = dispatch => ({
|
||||||
refreshThreadSubjects: threads => dispatch( refreshThreadSubjects(threads) ),
|
refreshThreadSubjects: threads => dispatch( refreshThreadSubjects(threads) ),
|
||||||
getSubjectComments: subjects => dispatch( getSubjectComments(subjects) ),
|
getSubjectComments: subjects => dispatch( getSubjectComments(subjects) ),
|
||||||
addSubject: subjects => dispatch( addSubject(subjects) ),
|
addSubject: subjects => dispatch( addSubject(subjects) ),
|
||||||
|
deleteSubject: subjects => dispatch( deleteSubject(subjects) ),
|
||||||
addComment: comments => dispatch( addComment(comments) ),
|
addComment: comments => dispatch( addComment(comments) ),
|
||||||
|
|
||||||
deactivate: () => dispatch( actions.deactivate() )
|
deactivate: () => dispatch( actions.deactivate() )
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,49 @@
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import { getAllThreads, getThreadSubjects } from '../../stores/threads/duck/operations'
|
import { getAllThreads, getThreadSubjects, addThread, deleteThread } from '../../stores/threads/duck/operations'
|
||||||
|
|
||||||
import '../../styles/indexForum.scss'
|
import '../../styles/indexForum.scss'
|
||||||
|
|
||||||
import ForumSubjects from './forumSubjects'
|
import ForumSubjects from './forumSubjects'
|
||||||
|
import ForumThreadUpdate from './indexForumUpdate'
|
||||||
|
|
||||||
const IndexForum = ({ user, threads, getAllThreads, getThreadSubjects }) => {
|
const IndexForum = ({
|
||||||
|
user,
|
||||||
|
threads, getAllThreads, getThreadSubjects, addThread, deleteThread }) => {
|
||||||
|
|
||||||
useEffect( () => { getAllThreads() }, [] )
|
useEffect( () => { getAllThreads() }, [] )
|
||||||
|
|
||||||
|
const [formDiv, setFormDiv] = useState(false)
|
||||||
|
const [updateFormDiv, setUpdateFormDiv] = useState( { isActive: false, thread_id: -1 } )
|
||||||
|
|
||||||
|
const [titleText, setTitleText] = useState(0)
|
||||||
|
|
||||||
|
const addThreadTitle = React.createRef()
|
||||||
|
|
||||||
|
const addNewThread = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if ( addThreadTitle.current.value !== '' ) {
|
||||||
|
let newThread = {
|
||||||
|
name: addThreadTitle.current.value,
|
||||||
|
user_id: user.id,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
addThread(newThread)
|
||||||
|
addThreadTitle.current.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteOldThread = (thread) => {
|
||||||
|
if( user.privilige === 3 ) {
|
||||||
|
let delSubject = {
|
||||||
|
token: user.token,
|
||||||
|
thread_id: thread.id
|
||||||
|
}
|
||||||
|
deleteThread(delSubject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (threads.isActive === false) {
|
if (threads.isActive === false) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -24,18 +57,63 @@ const IndexForum = ({ user, threads, getAllThreads, getThreadSubjects }) => {
|
||||||
</div>
|
</div>
|
||||||
<div className='forumItemsList'>
|
<div className='forumItemsList'>
|
||||||
{ threads.threadsList.map( thread =>
|
{ threads.threadsList.map( thread =>
|
||||||
<div
|
<div>
|
||||||
className={thread.moderator_privilige === 3 ? 'forumListItem adminDivColor' :
|
<div
|
||||||
(thread.moderator_privilige === 2 ? 'forumListItem moderDivColor' : 'forumListItem') }
|
className={thread.moderator_privilige === 3 ? 'forumListItem adminDivColor' :
|
||||||
key={thread.id}
|
(thread.moderator_privilige === 2 ? 'forumListItem moderDivColor' : 'forumListItem') }
|
||||||
onClick={ () => getThreadSubjects(thread) }>
|
key={thread.id}>
|
||||||
<p>{thread.name}</p>
|
<p onClick={ () => getThreadSubjects(thread) }>{thread.name}</p>
|
||||||
<p>moderator: {thread.moderator}</p>
|
{ (user.id === thread.user_id ||
|
||||||
|
user.privilige === 3) ? (
|
||||||
|
<div>
|
||||||
|
<button onClick={ () => setUpdateFormDiv( { isActive: !updateFormDiv.isActive, thread_id: thread.id } )}>
|
||||||
|
{ updateFormDiv.isActive ? 'Close Edit' : 'Edit Thread' }
|
||||||
|
</button>
|
||||||
|
{ user.privilige === 3 ? (
|
||||||
|
<button onClick={ () => deleteOldThread( thread )}>
|
||||||
|
Delete Thread
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
) }
|
||||||
|
<img src={ thread.moderator_avatar } />
|
||||||
|
<p>{ thread.moderator }</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<img src={ thread.moderator_avatar } />
|
||||||
|
<p>{ thread.moderator }</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<ForumThreadUpdate thread={ thread } thisThread={ updateFormDiv }/>
|
||||||
</div>
|
</div>
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
|
<div className={ formDiv === true ? 'forumFormSubject' : 'forumHiddenDiv' }>
|
||||||
|
<form onSubmit={ addNewThread }>
|
||||||
|
<input
|
||||||
|
name='addThreadTitle'
|
||||||
|
placeholder='Write a thread title'
|
||||||
|
maxLength='30'
|
||||||
|
ref={ addThreadTitle }
|
||||||
|
onChange={ e => setTitleText(e.target.value.length) }>
|
||||||
|
</input>
|
||||||
|
<p>Title: {titleText}/30</p>
|
||||||
|
<button>
|
||||||
|
Add Thread
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div className='forumFoot'>
|
<div className='forumFoot'>
|
||||||
Foot
|
{ user.privilige === 3 ? (
|
||||||
|
<button onClick={ () => setFormDiv( !formDiv ) }>
|
||||||
|
{ formDiv === true ? 'Close Add Thread' : 'Add Thread' }
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='indexForumMarginTop'>
|
<div className='indexForumMarginTop'>
|
||||||
|
|
@ -64,8 +142,10 @@ const mapStateToProps = state => ({
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
addThread: threads => dispatch( addThread(threads) ),
|
||||||
|
deleteThread: threads => dispatch( deleteThread(threads) ),
|
||||||
getAllThreads: () => dispatch( getAllThreads() ),
|
getAllThreads: () => dispatch( getAllThreads() ),
|
||||||
getThreadSubjects: thread => dispatch( getThreadSubjects(thread) )
|
getThreadSubjects: threads => dispatch( getThreadSubjects(threads) )
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(IndexForum)
|
export default connect(mapStateToProps, mapDispatchToProps)(IndexForum)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
import { updateThread } from '../../stores/threads/duck/operations'
|
||||||
|
|
||||||
|
import '../../styles/indexForum.scss'
|
||||||
|
|
||||||
|
const IndexForumUpdate = ({
|
||||||
|
user,
|
||||||
|
threads, getAllThreads, getThreadSubjects, updateThread,
|
||||||
|
thread, thisThread }) => {
|
||||||
|
|
||||||
|
const updateThreadTitle = React.createRef()
|
||||||
|
const [threadTitleText, setThreadTitleText] = useState(0)
|
||||||
|
|
||||||
|
const [selectThreadModeratorID, setSelectThreadModeratorID] = useState(-1)
|
||||||
|
|
||||||
|
const updateOldThread = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if ( updateThreadTitle.current.value !== '' && selectThreadModeratorID === -1 && user.privilige >= 2) {
|
||||||
|
let putThread = {
|
||||||
|
id: thread.id,
|
||||||
|
name: updateThreadTitle.current.value,
|
||||||
|
user_id: thread.user_id,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
updateThread(putThread)
|
||||||
|
updateThreadTitle.current.value = ''
|
||||||
|
} else if ( updateThreadTitle.current.value !== '' && user.privilige === 3 ) {
|
||||||
|
let putThread = {
|
||||||
|
id: thread.id,
|
||||||
|
name: updateThreadTitle.current.value,
|
||||||
|
user_id: selectThreadModeratorID === -1 ? thread.user_id : selectThreadModeratorID,
|
||||||
|
token: user.token
|
||||||
|
}
|
||||||
|
updateThread(putThread)
|
||||||
|
updateThreadTitle.current.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( thisThread.isActive === true && thisThread.thread_id === thread.id ) {
|
||||||
|
return (
|
||||||
|
<div className='forumFormSubject'>
|
||||||
|
<form onSubmit={ updateOldThread }>
|
||||||
|
<input
|
||||||
|
name='updateThreadTitleText'
|
||||||
|
placeholder={ thread.name }
|
||||||
|
ref={ updateThreadTitle }
|
||||||
|
cols='150'
|
||||||
|
maxLength='30'
|
||||||
|
onChange={ e => setThreadTitleText( e.target.value.length ) }>
|
||||||
|
</input>
|
||||||
|
{ (user.privilige === 3) ? (
|
||||||
|
<div>
|
||||||
|
<select
|
||||||
|
name='updateThreadModerator'
|
||||||
|
onChange={ e => setSelectThreadModeratorID( e.target.value ) }>
|
||||||
|
<option value={ thread.user_id }>Choice Moderator ( actual: { thread.moderator } )</option>
|
||||||
|
{ user.allUsersList
|
||||||
|
.filter( userObject => userObject.privilige >= 2 )
|
||||||
|
.map( userObject =>
|
||||||
|
<option value={userObject.id}>{userObject.login}</option>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div></div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<p>{threadTitleText}/30</p>
|
||||||
|
<button>
|
||||||
|
Update thread
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className='forumHiddenDiv'>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
user: state.user,
|
||||||
|
threads: state.threads
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
updateThread: threads => dispatch( updateThread(threads) )
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(IndexForumUpdate)
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import React, { useEffect } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { getSubjectsThread } from '../stores/subjects/duck/operations'
|
|
||||||
|
|
||||||
import '../styles/index.scss'
|
|
||||||
|
|
||||||
const Index = ({subjects, getSubjectsThread}) =>{
|
|
||||||
|
|
||||||
useEffect( () => { getSubjectsThread() }, [])
|
|
||||||
|
|
||||||
return <ul>
|
|
||||||
{subjects.list.map(subject => <li>{subject}</li>)}
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
|
|
||||||
// do odczytu globalnego state'a
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
subjects: state.subjects
|
|
||||||
})
|
|
||||||
|
|
||||||
// do modyfikacji globalnego state'a
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
getSubjectsThread: () => dispatch( getSubjectsThread() )
|
|
||||||
})
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Index)
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import React from 'react'
|
|
||||||
import { connect } from 'react-redux'
|
|
||||||
import actions from '../stores/subjects/duck/actions'
|
|
||||||
|
|
||||||
const IndexForm = (props) => {
|
|
||||||
|
|
||||||
const subjectInput = React.createRef()
|
|
||||||
|
|
||||||
const addSubject = (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
props.add(subjectInput.current.value)
|
|
||||||
|
|
||||||
subjectInput.current.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form onSubmit={addSubject}>
|
|
||||||
<input ref={subjectInput} />
|
|
||||||
<button type='submit'>Add Subject</button>
|
|
||||||
</form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
add: subject => dispatch(actions.add(subject))
|
|
||||||
})
|
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(IndexForm)
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
// Operations Redux
|
// Operations Redux
|
||||||
|
|
||||||
import { createSession, deleteSession, updateSession, registerUser } from '../stores/user/duck/operations'
|
import { createSession, deleteSession, updateSession, registerUser } from '../stores/user/duck/operations'
|
||||||
|
import { getChart } from '../stores/exchange/duck/operations'
|
||||||
|
|
||||||
// Actions Redux
|
// Actions Redux
|
||||||
|
|
||||||
|
|
@ -16,6 +17,7 @@ import '../styles/index.scss'
|
||||||
// Components
|
// Components
|
||||||
|
|
||||||
import MenuBar from './menuBar/menuBar'
|
import MenuBar from './menuBar/menuBar'
|
||||||
|
import Chat from './chat/indexChat'
|
||||||
|
|
||||||
import Exchange from './exchange/indexExchange'
|
import Exchange from './exchange/indexExchange'
|
||||||
import Forum from './forum/indexForum'
|
import Forum from './forum/indexForum'
|
||||||
|
|
@ -28,9 +30,12 @@ import BtcLogo from '../images/BtcLogo.png'
|
||||||
import ForumLogo from '../images/ForumLogo.png'
|
import ForumLogo from '../images/ForumLogo.png'
|
||||||
|
|
||||||
const IndexInterface = ({
|
const IndexInterface = ({
|
||||||
user, movements,
|
user, movements, exchange,
|
||||||
createSession, deleteSession, updateSession, registerUser,
|
createSession, deleteSession, updateSession, registerUser,
|
||||||
setRegister, setEdit, setForum, setExchange, setAdminPanel, resetMovements}) => {
|
setRegister, setEdit, setForum, setExchange, setAdminPanel, resetMovements,
|
||||||
|
getChart }) => {
|
||||||
|
|
||||||
|
useEffect( () => { getChart() }, [] )
|
||||||
|
|
||||||
const loginInput = React.createRef()
|
const loginInput = React.createRef()
|
||||||
const passwordInput = React.createRef()
|
const passwordInput = React.createRef()
|
||||||
|
|
@ -235,6 +240,45 @@ const IndexInterface = ({
|
||||||
}
|
}
|
||||||
else if (user.privilige === 3) {
|
else if (user.privilige === 3) {
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
<div className='indexView'>
|
||||||
|
<video id='indexVideo' autoPlay muted loop>
|
||||||
|
<source src={VideoEx} type="video/mp4" />
|
||||||
|
</video>
|
||||||
|
<div className="interface">
|
||||||
|
<div className='exchangeBtt' onClick={ () => setExchange() }>
|
||||||
|
<img src={BtcLogo} />
|
||||||
|
</div>
|
||||||
|
<div className='forumBtt' onClick={ () => setForum() }>
|
||||||
|
<img src={ForumLogo} />
|
||||||
|
</div>
|
||||||
|
<div className='loginForm'>
|
||||||
|
<form>
|
||||||
|
<p>Welcome</p>
|
||||||
|
<p>{user.login}</p>
|
||||||
|
<br />
|
||||||
|
</form>
|
||||||
|
<button onClick={ () => setAdminPanel() }>
|
||||||
|
Admin Panel
|
||||||
|
</button>
|
||||||
|
<button onClick={ () => setEdit() }>
|
||||||
|
Edit Account
|
||||||
|
</button>
|
||||||
|
<form onSubmit={userLogout}>
|
||||||
|
<button>
|
||||||
|
Log out
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Chat />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
<div className='indexView'>
|
<div className='indexView'>
|
||||||
<video id='indexVideo' autoPlay muted loop>
|
<video id='indexVideo' autoPlay muted loop>
|
||||||
<source src={VideoEx} type="video/mp4" />
|
<source src={VideoEx} type="video/mp4" />
|
||||||
|
|
@ -252,10 +296,7 @@ const IndexInterface = ({
|
||||||
<p>{user.login}</p>
|
<p>{user.login}</p>
|
||||||
<br />
|
<br />
|
||||||
</form>
|
</form>
|
||||||
<button onClick={ () => setAdminPanel() }>
|
<button onClick={ () => setEdit()}>
|
||||||
Admin Panel
|
|
||||||
</button>
|
|
||||||
<button onClick={ () => setEdit() }>
|
|
||||||
Edit Account
|
Edit Account
|
||||||
</button>
|
</button>
|
||||||
<form onSubmit={userLogout}>
|
<form onSubmit={userLogout}>
|
||||||
|
|
@ -266,37 +307,7 @@ const IndexInterface = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
<Chat />
|
||||||
}
|
|
||||||
else {
|
|
||||||
return (
|
|
||||||
<div className='indexView'>
|
|
||||||
<video id='indexVideo' autoPlay muted loop>
|
|
||||||
<source src={VideoEx} type="video/mp4" />
|
|
||||||
</video>
|
|
||||||
<div className="interface">
|
|
||||||
<div className='exchangeBtt' onClick={ () => setExchange() }>
|
|
||||||
<img src={BtcLogo} />
|
|
||||||
</div>
|
|
||||||
<div className='forumBtt' onClick={ () => setForum() }>
|
|
||||||
<img src={ForumLogo} />
|
|
||||||
</div>
|
|
||||||
<div className='loginForm'>
|
|
||||||
<form>
|
|
||||||
<p>Welcome</p>
|
|
||||||
<p>{user.login}</p>
|
|
||||||
<br />
|
|
||||||
</form>
|
|
||||||
<button onClick={ () => setEdit()}>
|
|
||||||
Edit Account
|
|
||||||
</button>
|
|
||||||
<form onSubmit={userLogout}>
|
|
||||||
<button>
|
|
||||||
Log out
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -304,6 +315,7 @@ const IndexInterface = ({
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
user: state.user,
|
user: state.user,
|
||||||
|
exchange: state.exchange,
|
||||||
movements: state.movements
|
movements: state.movements
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -318,7 +330,9 @@ const mapDispatchToProps = dispatch => ({
|
||||||
setExchange: movements => dispatch( actions.exchange() ),
|
setExchange: movements => dispatch( actions.exchange() ),
|
||||||
setForum: movements => dispatch( actions.forum() ),
|
setForum: movements => dispatch( actions.forum() ),
|
||||||
setAdminPanel: movements => dispatch( actions.adminPanel() ),
|
setAdminPanel: movements => dispatch( actions.adminPanel() ),
|
||||||
resetMovements: movements => dispatch( actions.reset() )
|
resetMovements: movements => dispatch( actions.reset() ),
|
||||||
|
|
||||||
|
getChart: exchange => dispatch( getChart(exchange) )
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(IndexInterface)
|
export default connect(mapStateToProps, mapDispatchToProps)(IndexInterface)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export const useInterval = (callback, delay) => {
|
||||||
|
|
||||||
|
const savedCallback = useRef();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
savedCallback.current = callback;
|
||||||
|
}, [callback]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function tick() {
|
||||||
|
savedCallback.current();
|
||||||
|
}
|
||||||
|
if (delay !== null) {
|
||||||
|
let id = setInterval(tick, delay);
|
||||||
|
return () => clearInterval(id);
|
||||||
|
}
|
||||||
|
}, [delay]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useInterval
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
|
@ -2,13 +2,13 @@ import React from "react";
|
||||||
|
|
||||||
import IndexInterface from "../components/indexInterface"
|
import IndexInterface from "../components/indexInterface"
|
||||||
|
|
||||||
import store from "../stores/store";
|
import { store } from "../stores/store";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
|
||||||
import '../styles/general.scss'
|
import '../styles/general.scss'
|
||||||
|
|
||||||
const IndexPage = () => (
|
const IndexPage = () => (
|
||||||
<Provider store={store}>
|
<Provider store={ store }>
|
||||||
<IndexInterface />
|
<IndexInterface />
|
||||||
</Provider>
|
</Provider>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const address = 'http://localhost:9090'//'http://tbs093a.pythonanywhere.com'
|
||||||
|
export const webSocketAddress = 'ws://localhost:9090/ws/'
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import types from './types'
|
||||||
|
|
||||||
|
const wsConnect = (host, lobby) => ({
|
||||||
|
type: types.WS_CONNECT, host, lobby
|
||||||
|
});
|
||||||
|
|
||||||
|
const wsSend = host => ({
|
||||||
|
type: types.WS_SEND, host
|
||||||
|
});
|
||||||
|
|
||||||
|
const wsDisconnect = host => ({
|
||||||
|
type: types.WS_DISCONNECT, host
|
||||||
|
});
|
||||||
|
|
||||||
|
const wsSaveMessage = host => ({
|
||||||
|
type: types.WS_SAVE_MESSAGE, host
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRooms = host => ({
|
||||||
|
type: types.GET_ROOMS_LIST, host
|
||||||
|
})
|
||||||
|
|
||||||
|
export default {
|
||||||
|
wsConnect,
|
||||||
|
wsSend,
|
||||||
|
wsDisconnect,
|
||||||
|
wsSaveMessage,
|
||||||
|
getRooms
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import chatReducer from './reducers'
|
||||||
|
export { default as chatTypes } from './types'
|
||||||
|
export { default as chatActions } from './actions'
|
||||||
|
|
||||||
|
export default chatReducer
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import actions from './actions'
|
||||||
|
import { webSocketAddress, address } from './../../apiAddress'
|
||||||
|
|
||||||
|
export const chatOnOpen = ( data ) =>
|
||||||
|
async ( dispatch ) => {
|
||||||
|
dispatch(actions.wsConnect( webSocketAddress + '' + data + '/', data))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const chatOnMessage = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
dispatch(actions.wsSaveMessage(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const chatOnClose = () =>
|
||||||
|
async ( dispatch ) => {
|
||||||
|
dispatch(actions.wsDisconnect())
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchGetRooms = async () => {
|
||||||
|
const response = await
|
||||||
|
fetch (
|
||||||
|
address + '/chat/', {
|
||||||
|
method: 'GET',
|
||||||
|
credentials: 'same-origin'
|
||||||
|
})
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getChatRooms = () =>
|
||||||
|
async ( dispatch ) => {
|
||||||
|
let roomList = await fetchGetRooms()
|
||||||
|
dispatch(actions.getRooms(roomList))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import types from './types'
|
||||||
|
|
||||||
|
const INITIAL_STATE = {
|
||||||
|
host: '',
|
||||||
|
lobby: '',
|
||||||
|
connected: false,
|
||||||
|
messages: [],
|
||||||
|
rooms: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatReducer = ( state = INITIAL_STATE, action ) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.GET_ROOMS_LIST:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
rooms: action.host
|
||||||
|
}
|
||||||
|
case types.WS_CONNECT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
connected: true,
|
||||||
|
lobby: action.lobby,
|
||||||
|
host: action.host,
|
||||||
|
webSocket: new WebSocket(action.host)
|
||||||
|
}
|
||||||
|
case types.WS_SAVE_MESSAGE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
messages: [...state.messages, action.host]
|
||||||
|
}
|
||||||
|
case types.WS_DISCONNECT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
webSocket: '',
|
||||||
|
lobby: '',
|
||||||
|
connected: false,
|
||||||
|
messages: [],
|
||||||
|
host: ''
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default chatReducer
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
const WS_CONNECT = 'WS_CONNECT'
|
||||||
|
const WS_SEND = 'WS_SEND'
|
||||||
|
const WS_SAVE_MESSAGE = 'WS_SAVE_MESSAGE'
|
||||||
|
const WS_DISCONNECT = 'WS_DISCONNECT'
|
||||||
|
const GET_ROOMS_LIST = 'GET_ROOMS_LIST'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
WS_CONNECT,
|
||||||
|
WS_SEND,
|
||||||
|
WS_SAVE_MESSAGE,
|
||||||
|
WS_DISCONNECT,
|
||||||
|
GET_ROOMS_LIST
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,11 @@ const getRatingsComment = item => ({
|
||||||
type: types.GET_COMMENTS_RATINGS, item
|
type: types.GET_COMMENTS_RATINGS, item
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const addComment = item => ({
|
||||||
|
type: types.ADD_COMMENT, item
|
||||||
|
})
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getRatingsComment
|
getRatingsComment,
|
||||||
|
addComment
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import actions from './actions'
|
import actions from './actions'
|
||||||
|
import { address } from './../../apiAddress'
|
||||||
|
|
||||||
const fetchRatingsComment = async (comment) => {
|
const fetchRatingsComment = async (comment) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch ('http://localhost:8001/index/comment/' + comment.id + '/rating', {
|
fetch (address + '/index/comment/' + comment.id + '/rating', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials: 'same-origin'
|
credentials: 'same-origin'
|
||||||
});
|
});
|
||||||
|
|
@ -10,7 +11,7 @@ const fetchRatingsComment = async (comment) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchAddRating = async (data) => {
|
const fetchAddRating = async (data) => {
|
||||||
fetch ('http://localhost:8001/index/comment/' + data.comment_id + '/rating', {
|
fetch (address + '/index/comment/' + data.comment_id + '/rating', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
@ -18,7 +19,7 @@ const fetchAddRating = async (data) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchUpdateRating = async (rating) => {
|
const fetchUpdateRating = async (rating) => {
|
||||||
fetch ('http://localhost:8001/index/rating/' + rating.id, {
|
fetch (address + '/index/rating/' + rating.id, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(rating)
|
body: JSON.stringify(rating)
|
||||||
|
|
@ -48,7 +49,7 @@ export const updateRatingComment = (data) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchAddComment = async (data) => {
|
const fetchAddComment = async (data) => {
|
||||||
fetch ('http://localhost:8001/index/subject/' + data.subject_id + '/comment', {
|
fetch (address + '/index/subject/' + data.subject_id + '/comment', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
@ -56,7 +57,7 @@ const fetchAddComment = async (data) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchUpdateComment = async (data) => {
|
const fetchUpdateComment = async (data) => {
|
||||||
fetch ('http://localhost:8001/index/comment/' + data.id, {
|
fetch (address + '/index/comment/' + data.id, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
@ -64,7 +65,7 @@ const fetchUpdateComment = async (data) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchDeleteComment = async (data) => {
|
const fetchDeleteComment = async (data) => {
|
||||||
fetch ('http://localhost:8001/index/comment/' + data.id, {
|
fetch (address + '/index/comment/' + data.id, {
|
||||||
method: 'Delete',
|
method: 'Delete',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
const GET_COMMENTS_RATINGS = 'GET_COMMENTS_RATINGS'
|
const GET_COMMENTS_RATINGS = 'GET_COMMENTS_RATINGS'
|
||||||
|
const ADD_COMMENT = 'ADD_COMMENT'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
GET_COMMENTS_RATINGS
|
GET_COMMENTS_RATINGS,
|
||||||
|
ADD_COMMENT
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import types from './types'
|
||||||
|
|
||||||
|
const setChart = item => ({
|
||||||
|
type: types.GET_CANDLES_CHART, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const setTriggers = item => ({
|
||||||
|
type: types.GET_USER_TRIGGERS, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const setNotifications = item => ({
|
||||||
|
type: types.GET_USER_NOTIFICATIONS, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const setTransactions = item => ({
|
||||||
|
type: types.GET_USER_TRANSACTIONS, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const deleteOldNotification = item => ({
|
||||||
|
type: types.DELETE_NOTIFICATION, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const addNewTrigger = item => ({
|
||||||
|
type: types.ADD_NEW_TRIGGER, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const setNewPrognosis = item => ({
|
||||||
|
type: types.NEW_PROGNOSIS, item
|
||||||
|
})
|
||||||
|
|
||||||
|
const reset = item => ({
|
||||||
|
type: types.RESET, item
|
||||||
|
})
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setChart,
|
||||||
|
setTriggers,
|
||||||
|
setNotifications,
|
||||||
|
setTransactions,
|
||||||
|
deleteOldNotification,
|
||||||
|
addNewTrigger,
|
||||||
|
setNewPrognosis,
|
||||||
|
reset
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import exchangeReducer from './reducers'
|
||||||
|
export { default as exchangeTypes } from './types'
|
||||||
|
export { default as exchangeActions } from './actions'
|
||||||
|
|
||||||
|
export default exchangeReducer
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
import actions from './actions'
|
||||||
|
import { address } from './../../apiAddress'
|
||||||
|
|
||||||
|
const fetchGetChart = async () => {
|
||||||
|
const response = await
|
||||||
|
fetch (
|
||||||
|
address + '/index/exchange/' + 1800, {
|
||||||
|
method: 'GET',
|
||||||
|
credential: 'same-origin'
|
||||||
|
})
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchGetUserTriggers = async (userID) => {
|
||||||
|
const response = await
|
||||||
|
fetch (
|
||||||
|
address + '/index/user/' + userID + '/trigger', {
|
||||||
|
method: 'GET',
|
||||||
|
credential: 'same-origin'
|
||||||
|
})
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchGetUserTransactions = async (userID) => {
|
||||||
|
const response = await
|
||||||
|
fetch (
|
||||||
|
address + '/index/user/' + userID + '/transaction', {
|
||||||
|
method: 'GET',
|
||||||
|
credential: 'same-origin'
|
||||||
|
})
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchGetUserNotifications = async (userID) => {
|
||||||
|
const response = await
|
||||||
|
fetch (
|
||||||
|
address + '/index/user/' + userID + '/notification', {
|
||||||
|
method: 'GET',
|
||||||
|
credential: 'same-origin'
|
||||||
|
})
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchAddTrigger = async (data) => {
|
||||||
|
fetch (
|
||||||
|
address + '/index/user/' + data.user_id + '/trigger', {
|
||||||
|
method: 'POST',
|
||||||
|
credential: 'same-origin',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchPrognosis = async (data) => {
|
||||||
|
const response = await fetch (
|
||||||
|
address + '/index/exchange/1800/prognosis/' + data.price, {
|
||||||
|
method: 'GET',
|
||||||
|
credential: 'same-origin'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const json = response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchDeleteNotification = async (data) => {
|
||||||
|
const response = await fetch (
|
||||||
|
address + '/index/notification/' + data.id, {
|
||||||
|
method: 'DELETE',
|
||||||
|
credential: 'same-origin',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const json = response.json()
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getChart = () =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const chart = await fetchGetChart()
|
||||||
|
dispatch(actions.setChart(chart))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserTriggers = (userID) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const triggers = await fetchGetUserTriggers(userID)
|
||||||
|
dispatch(actions.setTriggers(triggers))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserTransactions = (userID) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const transactions = await fetchGetUserTransactions(userID)
|
||||||
|
dispatch(actions.setTransactions(transactions))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserNotifications = (userID) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const notifications = await fetchGetUserNotifications(userID)
|
||||||
|
dispatch(actions.setNotifications(notifications))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addTrigger = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
await fetchAddTrigger(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const checkPrognosis = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const prognosis = await fetchPrognosis(data)
|
||||||
|
dispatch(actions.setNewPrognosis(prognosis))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteNotification = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
dispatch(actions.deleteOldNotification(data))
|
||||||
|
await fetchDeleteNotification(data)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import types from './types'
|
||||||
|
|
||||||
|
const INITIAL_STATE = {
|
||||||
|
candles: [],
|
||||||
|
userTriggers: [],
|
||||||
|
userNotifications: [],
|
||||||
|
userTransactions: [],
|
||||||
|
prognosis: {
|
||||||
|
price_forecast: 0,
|
||||||
|
percent_of_difference: 0,
|
||||||
|
course_on_payment: 0,
|
||||||
|
svg_of_all: 0,
|
||||||
|
date_of_transaction: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exchangeReducer = (state = INITIAL_STATE, action) => {
|
||||||
|
switch(action.type) {
|
||||||
|
case types.GET_CANDLES_CHART:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
candles: action.item
|
||||||
|
}
|
||||||
|
case types.GET_USER_TRIGGERS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
userTriggers: action.item
|
||||||
|
}
|
||||||
|
case types.GET_USER_NOTIFICATIONS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
userNotifications: action.item
|
||||||
|
}
|
||||||
|
case types.GET_USER_TRANSACTIONS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
userTransactions: action.item
|
||||||
|
}
|
||||||
|
case types.DELETE_NOTIFICATION:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
userNotifications: state.userNotifications.filter(
|
||||||
|
notify => notify.id !== action.item.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case types.NEW_PROGNOSIS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
prognosis: action.item
|
||||||
|
}
|
||||||
|
case types.RESET:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
userTriggers: [],
|
||||||
|
userNotifications: [],
|
||||||
|
userTransactions: [],
|
||||||
|
prognosis: {
|
||||||
|
price_forecast: 0,
|
||||||
|
percent_of_difference: 0,
|
||||||
|
course_on_payment: 0,
|
||||||
|
svg_of_all: 0,
|
||||||
|
date_of_transaction: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default exchangeReducer
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
const GET_CANDLES_CHART = 'GET_CANDLES_CHART'
|
||||||
|
const GET_USER_TRIGGERS = 'GET_USER_TRIGGERS'
|
||||||
|
const GET_USER_NOTIFICATIONS = 'GET_USER_NOTIFICATIONS'
|
||||||
|
const GET_USER_TRANSACTIONS = 'GET_USER_TRANSACTIONS'
|
||||||
|
const DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'
|
||||||
|
const ADD_NEW_TRIGGER = 'ADD_NEW_TRIGGER'
|
||||||
|
const NEW_PROGNOSIS = 'NEW_PROGNOSIS'
|
||||||
|
const RESET = 'RESET'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
GET_CANDLES_CHART,
|
||||||
|
GET_USER_TRIGGERS,
|
||||||
|
GET_USER_NOTIFICATIONS,
|
||||||
|
GET_USER_TRANSACTIONS,
|
||||||
|
DELETE_NOTIFICATION,
|
||||||
|
ADD_NEW_TRIGGER,
|
||||||
|
NEW_PROGNOSIS,
|
||||||
|
RESET
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
export const loadState = () => {
|
||||||
|
try {
|
||||||
|
const serializedState = localStorage.getItem('state');
|
||||||
|
|
||||||
|
if (serializedState === null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(serializedState);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const saveState = (state) => {
|
||||||
|
try {
|
||||||
|
const serializedState = JSON.stringify(state);
|
||||||
|
localStorage.setItem('state', serializedState);
|
||||||
|
} catch (err) {
|
||||||
|
console.log('save in local storage error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,16 +1,23 @@
|
||||||
import { combineReducers } from 'redux'
|
import { combineReducers } from 'redux'
|
||||||
|
|
||||||
import movementsReducer from './movements/duck'
|
import movementsReducer from './movements/duck'
|
||||||
import commentReducer from './comments/duck'
|
import commentReducer from './comments/duck'
|
||||||
import subjectReducer from './subjects/duck'
|
import subjectReducer from './subjects/duck'
|
||||||
import threadReducer from './threads/duck'
|
import threadReducer from './threads/duck'
|
||||||
|
|
||||||
import userReducer from './user/duck'
|
import userReducer from './user/duck'
|
||||||
|
import chatReducer from './chat/duck'
|
||||||
|
|
||||||
|
import exchangeReducer from './exchange/duck'
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
user: userReducer,
|
user: userReducer,
|
||||||
|
chat: chatReducer,
|
||||||
threads: threadReducer,
|
threads: threadReducer,
|
||||||
subjects: subjectReducer,
|
subjects: subjectReducer,
|
||||||
comments: commentReducer,
|
comments: commentReducer,
|
||||||
movements: movementsReducer
|
movements: movementsReducer,
|
||||||
|
exchange: exchangeReducer
|
||||||
})
|
})
|
||||||
|
|
||||||
export default rootReducer
|
export default rootReducer
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,42 @@
|
||||||
import { createStore, applyMiddleware } from 'redux'
|
import { createStore, applyMiddleware } from 'redux'
|
||||||
import { composeWithDevTools } from 'redux-devtools-extension'
|
import { composeWithDevTools } from 'redux-devtools-extension'
|
||||||
import rootReducer from './reducers'
|
|
||||||
import thunk from 'redux-thunk'
|
import thunk from 'redux-thunk'
|
||||||
|
import rootReducer from './reducers'
|
||||||
|
import { saveState, loadState } from './localStorage';
|
||||||
|
import lodash from 'lodash';
|
||||||
|
|
||||||
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))
|
//const store = createStore(rootReducer) //, composeWithDevTools(applyMiddleware(thunk))
|
||||||
|
|
||||||
window.store = store
|
const persistedState = loadState();
|
||||||
|
|
||||||
export default store
|
export const store = createStore(rootReducer, persistedState, composeWithDevTools(applyMiddleware(thunk)))
|
||||||
|
|
||||||
|
// console.log(store.getState())
|
||||||
|
|
||||||
|
store.subscribe(() => {
|
||||||
|
saveState({
|
||||||
|
user: store.getState().user,
|
||||||
|
chat: store.getState().chat,
|
||||||
|
exchange: store.getState().exchange,
|
||||||
|
comments: store.getState().comments,
|
||||||
|
subjects: store.getState().subjects,
|
||||||
|
threads: store.getState().threads,
|
||||||
|
movements: store.getState().movements
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
store.subscribe(lodash.throttle(() => {
|
||||||
|
saveState({
|
||||||
|
user: store.getState().user,
|
||||||
|
chat: store.getState().chat,
|
||||||
|
exchange: store.getState().exchange,
|
||||||
|
comments: store.getState().comments,
|
||||||
|
subjects: store.getState().subjects,
|
||||||
|
threads: store.getState().threads,
|
||||||
|
movements: store.getState().movements
|
||||||
|
});
|
||||||
|
}, 1000));
|
||||||
|
|
||||||
|
export default preloadedState => {
|
||||||
|
return createStore(rootReducer, preloadedState)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,13 @@ const deactivate = item => ({
|
||||||
type: types.DEACTIVATE, item
|
type: types.DEACTIVATE, item
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const addComment = item => ({
|
||||||
|
type: types.ADD_COMMENT, item
|
||||||
|
})
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getSubjectComments,
|
getSubjectComments,
|
||||||
activate,
|
activate,
|
||||||
deactivate
|
deactivate,
|
||||||
|
addComment
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import actions from './actions'
|
import actions from './actions'
|
||||||
|
import { address } from './../../apiAddress'
|
||||||
|
|
||||||
const fetchSubjectComments = async (subject) => {
|
const fetchSubjectComments = async (subject) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch('http://localhost:8001/index/subject/' + subject.id + '/comment', {
|
fetch(address + '/index/subject/' + subject.id + '/comment', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials: 'same-origin'
|
credentials: 'same-origin'
|
||||||
});
|
});
|
||||||
|
|
@ -24,7 +25,7 @@ export const getSubjectComments = (data) =>
|
||||||
|
|
||||||
const fetchAddSubject = async (data) => {
|
const fetchAddSubject = async (data) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch('http://localhost:8001/index/thread/' + data.thread_id + '/subject', {
|
fetch(address + '/index/thread/' + data.thread_id + '/subject', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
@ -39,7 +40,7 @@ const fetchAddSubject = async (data) => {
|
||||||
|
|
||||||
const fetchPutSubject = async (data) => {
|
const fetchPutSubject = async (data) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch('http://localhost:8001/index/subject/' + data.id, {
|
fetch(address + '/index/subject/' + data.id, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
@ -54,7 +55,7 @@ const fetchPutSubject = async (data) => {
|
||||||
|
|
||||||
const fetchDeleteSubject = async (data) => {
|
const fetchDeleteSubject = async (data) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch('http://localhost:8001/index/subject/' + data.id, {
|
fetch(address + '/index/subject/' + data.subject_id, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ const subjectReducer = (state = INITIAL_STATE, action) => {
|
||||||
actualSubjectAuthorID: -1,
|
actualSubjectAuthorID: -1,
|
||||||
isActive: false
|
isActive: false
|
||||||
}
|
}
|
||||||
|
case types.ADD_COMMENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
commentsList: [...state.commentsList, action.item]
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
const GET_SUBJECT_COMMENTS = 'GET_SUBJECT_COMMENTS'
|
const GET_SUBJECT_COMMENTS = 'GET_SUBJECT_COMMENTS'
|
||||||
const ACTIVATE = 'ACTIVATE'
|
const ACTIVATE = 'ACTIVATE'
|
||||||
const DEACTIVATE = 'DEACTIVATE'
|
const DEACTIVATE = 'DEACTIVATE'
|
||||||
|
const ADD_COMMENT = 'ADD_COMMENT'
|
||||||
|
|
||||||
export default{
|
export default{
|
||||||
GET_SUBJECT_COMMENTS,
|
GET_SUBJECT_COMMENTS,
|
||||||
ACTIVATE,
|
ACTIVATE,
|
||||||
DEACTIVATE
|
DEACTIVATE,
|
||||||
|
ADD_COMMENT
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import actions from './actions'
|
import actions from './actions'
|
||||||
|
import { address } from './../../apiAddress'
|
||||||
|
|
||||||
const fetchGetAll = async () => {
|
const fetchGetAll = async () => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/thread', {
|
address + '/index/thread', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credential: 'same-origin'
|
credential: 'same-origin'
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +15,7 @@ const fetchGetAll = async () => {
|
||||||
const fetchGetSubjects = async (threadID) => {
|
const fetchGetSubjects = async (threadID) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch(
|
fetch(
|
||||||
'http://localhost:8001/index/thread/' + threadID + '/subject', {
|
address + '/index/thread/' + threadID + '/subject', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credential: 'same-origin'
|
credential: 'same-origin'
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +23,43 @@ const fetchGetSubjects = async (threadID) => {
|
||||||
return response.json()
|
return response.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchAddThread = async (data) => {
|
||||||
|
const response = await
|
||||||
|
fetch(
|
||||||
|
address + '/index/thread', {
|
||||||
|
method: 'POST',
|
||||||
|
credential: 'same-origin',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchUpdateThread = async (data) => {
|
||||||
|
const response = await
|
||||||
|
fetch(
|
||||||
|
address + '/index/thread/' + data.id, {
|
||||||
|
method: 'PUT',
|
||||||
|
credential: 'same-origin',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchDeleteThread = async (data) => {
|
||||||
|
const response = await
|
||||||
|
fetch(
|
||||||
|
address + '/index/thread/' + data.thread_id, {
|
||||||
|
method: 'DELETE',
|
||||||
|
credential: 'same-origin',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getAllThreads = () =>
|
export const getAllThreads = () =>
|
||||||
async (dispatch) => {
|
async (dispatch) => {
|
||||||
const allThreads = await fetchGetAll()
|
const allThreads = await fetchGetAll()
|
||||||
|
|
@ -41,3 +79,18 @@ export const getThreadSubjects = (data) =>
|
||||||
dispatch( actions.activate(data) )
|
dispatch( actions.activate(data) )
|
||||||
dispatch( actions.getThreadSubjects(subjects) )
|
dispatch( actions.getThreadSubjects(subjects) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addThread = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const subjects = await fetchAddThread(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateThread = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const subjects = await fetchUpdateThread(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteThread = (data) =>
|
||||||
|
async (dispatch) => {
|
||||||
|
const subjects = await fetchDeleteThread(data)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import actions from './actions'
|
import actions from './actions'
|
||||||
|
import { address } from './../../apiAddress'
|
||||||
|
|
||||||
var jwtDecode = require('jwt-decode')
|
var jwtDecode = require('jwt-decode')
|
||||||
|
|
||||||
const fetchLogin = async (user) => {
|
const fetchLogin = async (user) => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/authUser', {
|
address + '/index/authUser', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credential: 'same-origin',
|
credential: 'same-origin',
|
||||||
body: JSON.stringify(user),
|
body: JSON.stringify(user),
|
||||||
|
|
@ -16,7 +17,7 @@ const fetchLogin = async (user) => {
|
||||||
|
|
||||||
const fetchLogout = async (userToken) => {
|
const fetchLogout = async (userToken) => {
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/authUser', {
|
address + '/index/authUser', {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
credential: 'same-origin',
|
credential: 'same-origin',
|
||||||
body: JSON.stringify(userToken),
|
body: JSON.stringify(userToken),
|
||||||
|
|
@ -26,7 +27,7 @@ const fetchLogout = async (userToken) => {
|
||||||
|
|
||||||
const fetchUpdate = async (user) => {
|
const fetchUpdate = async (user) => {
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/user/' + user.id, {
|
address + '/index/user/' + user.id, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
credential: 'same-origin',
|
credential: 'same-origin',
|
||||||
body: JSON.stringify(user),
|
body: JSON.stringify(user),
|
||||||
|
|
@ -35,7 +36,7 @@ const fetchUpdate = async (user) => {
|
||||||
|
|
||||||
const fetchRegister = async (user) => {
|
const fetchRegister = async (user) => {
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/user', {
|
address + '/index/user', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credential: 'same-origin',
|
credential: 'same-origin',
|
||||||
body: JSON.stringify(user),
|
body: JSON.stringify(user),
|
||||||
|
|
@ -46,12 +47,12 @@ const fetchRegister = async (user) => {
|
||||||
const fetchGetAllUsers = async () => {
|
const fetchGetAllUsers = async () => {
|
||||||
const response = await
|
const response = await
|
||||||
fetch (
|
fetch (
|
||||||
'http://localhost:8001/index/user', {
|
address + '/index/user', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credential: 'same-origin'
|
credential: 'same-origin'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const json = await response.json()
|
const json = response.json()
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,9 +62,7 @@ export const createSession = (data) =>
|
||||||
const token = await fetchLogin(data)
|
const token = await fetchLogin(data)
|
||||||
let user = jwtDecode(token.token)
|
let user = jwtDecode(token.token)
|
||||||
|
|
||||||
let allUsers = 'None'
|
let allUsers = await fetchGetAllUsers()
|
||||||
if ( user.payload.privilige > 1 )
|
|
||||||
allUsers = await fetchGetAllUsers()
|
|
||||||
|
|
||||||
let userFull = {
|
let userFull = {
|
||||||
token: token.token,
|
token: token.token,
|
||||||
|
|
@ -79,7 +78,7 @@ export const createSession = (data) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateSession = (data) =>
|
export const updateSession = (data) =>
|
||||||
async (dispatch) => {
|
async () => {
|
||||||
await fetchUpdate(data)
|
await fetchUpdate(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,6 +89,6 @@ export const deleteSession = (data) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const registerUser = (data) =>
|
export const registerUser = (data) =>
|
||||||
async (dispatch) => {
|
async () => {
|
||||||
await fetchRegister(data)
|
await fetchRegister(data)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ const INITIAL_STATE = {
|
||||||
privilige: '',
|
privilige: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
token: '',
|
token: '',
|
||||||
isActive: false
|
isActive: false,
|
||||||
|
allUsersList: []
|
||||||
}
|
}
|
||||||
|
|
||||||
const userReducer = (state = INITIAL_STATE, action) => {
|
const userReducer = (state = INITIAL_STATE, action) => {
|
||||||
|
|
@ -20,11 +21,12 @@ const userReducer = (state = INITIAL_STATE, action) => {
|
||||||
email: action.item.email,
|
email: action.item.email,
|
||||||
avatar: action.item.avatar,
|
avatar: action.item.avatar,
|
||||||
token: action.item.token,
|
token: action.item.token,
|
||||||
isActive: true,
|
allUsersList: action.item.allUsersList,
|
||||||
allUsersList: action.item.allUsersList
|
isActive: true
|
||||||
}
|
}
|
||||||
case types.LOGOUT_USER:
|
case types.LOGOUT_USER:
|
||||||
return {
|
return {
|
||||||
|
id: -1,
|
||||||
isActive: false
|
isActive: false
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin scrollStyle {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: rgba(22,28,29,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
@mixin inputStyle {
|
@mixin inputStyle {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
|
|
@ -26,7 +32,7 @@
|
||||||
border: 0px;
|
border: 0px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
color: rgba(117,82,29,1);
|
color: rgba(148,104,36,1); //rgba(117,82,29,1)
|
||||||
background-color: rgba(22,28,29,1);
|
background-color: rgba(22,28,29,1);
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
|
|
||||||
|
|
@ -41,14 +47,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,700);
|
||||||
|
|
||||||
@mixin fontStyle {
|
@mixin fontStyle {
|
||||||
color: rgba(117,82,29,1);
|
color: rgba(148,104,36,1); //rgba(117,82,29,1)
|
||||||
|
font-family: 'Ubuntu';
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin backgroundDivMenubarStyle{
|
@mixin backgroundColorOnly {
|
||||||
|
background-color: rgba(22,28,29,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin backgroundDivMenubarStyle {
|
||||||
background-color: rgba(22,28,29,0.2);
|
background-color: rgba(22,28,29,0.2);
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-color: rgba(117,82,29,0.7);
|
border-color: rgba(117,82,29,0.7);
|
||||||
|
|
@ -89,3 +102,28 @@
|
||||||
rgba(9,17,121,0.1) 10%,
|
rgba(9,17,121,0.1) 10%,
|
||||||
rgba(0,212,255,0) 50%);
|
rgba(0,212,255,0) 50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: rgba(131, 28, 20, 1);
|
||||||
|
border-radius: 2px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageFullStyle {
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 2.5%;
|
||||||
|
width: auto;
|
||||||
|
height: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,14 @@ $widthRT: 40px;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 250px;
|
height: 250px;
|
||||||
|
|
||||||
background-color: rgba(117,82,29,1);
|
border: solid 1px;
|
||||||
|
border-color: rgba(117,82,29,1);
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratingValue {
|
.ratingValue {
|
||||||
|
width: $widthRT;
|
||||||
|
height: 250px;
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
@include scrollStyle
|
||||||
|
}
|
||||||
input {
|
input {
|
||||||
@include inputStyle
|
@include inputStyle
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
||||||
@include BigButtonStyle
|
@include BigButtonStyle;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@include inputStyle
|
@include inputStyle;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
@import 'index';
|
||||||
|
@import 'elements';
|
||||||
|
|
||||||
|
@mixin ChatMessageStyle {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
max-width: 190px;
|
||||||
|
|
||||||
|
font-family: Ubuntu;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin ChatWindowStyle {
|
||||||
|
position: fixed;
|
||||||
|
height: 400px;
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
margin-left: 50px;
|
||||||
|
margin-top: -50px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatMenuBar {
|
||||||
|
width: 300px;
|
||||||
|
height: 40px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
background-color: rgba(22,28,29,0.8);
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: rgba(22,28,29,1);
|
||||||
|
background-color: rgba(117,82,29,1);
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.chatBody {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.lobbyMessage {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
border-top: 1px dashed;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-left: 5%;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
.lobbyName {
|
||||||
|
margin-top: 15px;
|
||||||
|
width: 45%;
|
||||||
|
padding-left: 5%;
|
||||||
|
float: left;
|
||||||
|
text-align: left;
|
||||||
|
font-family: Ubuntu;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.listMessage {
|
||||||
|
width: 100%;
|
||||||
|
height: 250px;
|
||||||
|
border-top: 1px dashed;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
.chatListItem {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Ubuntu;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rowMessage {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 40px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.chatAvatar {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
border-radius: 50px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chatMessageDisplay {
|
||||||
|
display: block;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
.userMessage {
|
||||||
|
@include ChatMessageStyle;
|
||||||
|
color: rgba(22,28,29,1);
|
||||||
|
background-color: rgba(117,82,29,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.otherMessage {
|
||||||
|
@include ChatMessageStyle;
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messageWithImage {
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
border-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.textMessage {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
border-top: 1px dashed;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-left: 2%;
|
||||||
|
width: 55%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.inputFile {
|
||||||
|
margin-right: -8%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.inputFile {
|
||||||
|
width: 10%;
|
||||||
|
height: 8%;
|
||||||
|
margin-left: -10%;
|
||||||
|
margin-top: 2%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputFile {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-left: 2%;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatWindowHide {
|
||||||
|
@include BigButtonStyle;
|
||||||
|
@include ChatWindowStyle;
|
||||||
|
|
||||||
|
img {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatWindowChangeLobby {
|
||||||
|
@include BigButtonStyle;
|
||||||
|
@include ChatWindowStyle;
|
||||||
|
|
||||||
|
margin-top: -350px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatWindowOpen {
|
||||||
|
@include BigButtonStyle;
|
||||||
|
@include ChatWindowStyle;
|
||||||
|
|
||||||
|
margin-top: -400px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,257 @@
|
||||||
|
@import 'elements';
|
||||||
|
|
||||||
|
.indexExchange {
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding-top: 175px; //175px
|
||||||
|
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
@mixin centerEx {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin exchangeChart {
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 600px; //600px
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
@include centerEx;
|
||||||
|
.sectionChart {
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: 5px;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
opacity: 0.6;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionCandle {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
@include centerEx;
|
||||||
|
|
||||||
|
.candle {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
.candleMaxValue {
|
||||||
|
@include centerEx;
|
||||||
|
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candleHigh {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candleLow {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candleMinValue {
|
||||||
|
@include centerEx;
|
||||||
|
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sectionVolumen {
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
@include centerEx;
|
||||||
|
|
||||||
|
.volumen {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
background: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeChartGuest {
|
||||||
|
@include exchangeChart;
|
||||||
|
|
||||||
|
margin-top: 5vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeChartUser {
|
||||||
|
@include exchangeChart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin exchangeInterface {
|
||||||
|
|
||||||
|
z-index: -1;
|
||||||
|
width: 100%;
|
||||||
|
height: 70%;
|
||||||
|
position: fixed;
|
||||||
|
top: 15%;
|
||||||
|
right: 0px;
|
||||||
|
|
||||||
|
.candleInformation {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 16.66%;
|
||||||
|
text-align: center;
|
||||||
|
float: left;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeEmptySpace {
|
||||||
|
@include exchangeInterface;
|
||||||
|
}
|
||||||
|
.exchangeInterface {
|
||||||
|
@include exchangeInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeTriggerDativeY {
|
||||||
|
z-index: -1;
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
height: 1px;
|
||||||
|
background-color: rgba(117,82,29,1);
|
||||||
|
transform: margin 700ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeTriggerDativeX {
|
||||||
|
z-index: -1;
|
||||||
|
position: fixed;
|
||||||
|
width: 1px;
|
||||||
|
height: 590px;
|
||||||
|
background-color: rgba(117,82,29,1);
|
||||||
|
transform: margin 700ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exchangeInterfaceTwo {
|
||||||
|
background: rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin gapBetweenSectionsEx {
|
||||||
|
border-right: 2px dashed;
|
||||||
|
border-color: rgba(117,82,29,0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin exchangeDivInterface {
|
||||||
|
width: 31.25%;
|
||||||
|
height: 94%;
|
||||||
|
float: left;
|
||||||
|
padding-left: 1%;
|
||||||
|
padding-right: 1%;
|
||||||
|
padding-top: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include gapBetweenSectionsEx
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeTriggerDiv {
|
||||||
|
@include exchangeDivInterface;
|
||||||
|
|
||||||
|
form {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding-top: 10px;
|
||||||
|
width: 50%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
float: left;
|
||||||
|
width: 50%;
|
||||||
|
height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.triggerItemList {
|
||||||
|
width: 100%;
|
||||||
|
height: 75px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
.triggerItem {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangePrognosisDiv {
|
||||||
|
@include exchangeDivInterface;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 50%;
|
||||||
|
height: 10px;
|
||||||
|
float: left;
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exchangeNotificationsDiv {
|
||||||
|
@include exchangeDivInterface;
|
||||||
|
border-right: 0px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifyList {
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 120px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 90%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-left: 2.5%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.indexForum {
|
.indexForum {
|
||||||
@include backgroundDefaultDivStyle
|
@include backgroundDefaultDivStyle;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|
@ -48,8 +48,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.forumTitle {
|
.forumTitle {
|
||||||
@include forumDiv
|
@include forumDiv;
|
||||||
@include gapTopBetweenElements
|
@include gapTopBetweenElements;
|
||||||
p {
|
p {
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
float: left;
|
float: left;
|
||||||
|
|
@ -75,7 +75,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.forumItemsList {
|
.forumItemsList {
|
||||||
@include gapTopBetweenElements
|
@include gapTopBetweenElements;
|
||||||
|
|
||||||
.forumListItem:last-child{
|
.forumListItem:last-child{
|
||||||
border-bottom: 0px dashed;
|
border-bottom: 0px dashed;
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
padding-left: 5%;
|
padding-left: 5%;
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
|
|
||||||
@include gapBetweenItems
|
@include gapBetweenItems;
|
||||||
|
|
||||||
p:first-child {
|
p:first-child {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
|
|
@ -99,7 +99,8 @@
|
||||||
float: right;
|
float: right;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
min-width: 130px;
|
min-width: 120px;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -135,7 +136,7 @@
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
@include gapBetweenItems
|
@include gapBetweenItems;
|
||||||
|
|
||||||
&:last-child{
|
&:last-child{
|
||||||
border-bottom: 1px;
|
border-bottom: 1px;
|
||||||
|
|
@ -147,7 +148,7 @@
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@include gapBetweenSections
|
@include gapBetweenSections;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
|
@ -166,7 +167,7 @@
|
||||||
|
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
@include gapBetweenSections
|
@include gapBetweenSections;
|
||||||
}
|
}
|
||||||
.commentRating {
|
.commentRating {
|
||||||
width: 15%;
|
width: 15%;
|
||||||
|
|
@ -181,22 +182,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.forumFormSubject {
|
.forumFormSubject {
|
||||||
@include forumDiv
|
@include forumDiv;
|
||||||
|
|
||||||
height: auto;
|
height: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
|
|
||||||
@include gapTopBetweenElements
|
@include gapTopBetweenElements;
|
||||||
form {
|
form {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
input {
|
||||||
input, select {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
float: left;
|
float: left;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
}
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
|
@ -213,13 +218,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.forumFormComment {
|
.forumFormComment {
|
||||||
@include forumDiv
|
@include forumDiv;
|
||||||
|
|
||||||
height: auto;
|
height: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
|
|
||||||
@include gapTopBetweenElements
|
@include gapTopBetweenElements;
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
|
@ -235,7 +240,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.forumFoot {
|
.forumFoot {
|
||||||
@include forumDiv
|
@include forumDiv;
|
||||||
button {
|
button {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue