diff --git a/README.md b/README.md new file mode 100755 index 0000000..2b670dd --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ + +

+ + Gatsby + +

+

+ Gatsby's default starter +

+ +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 + +[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default) + + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..fcb8e7c --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +sudo sysctl fs.inotify.max_user_watches=524288 +gatsby clean +gatsby develop \ No newline at end of file diff --git a/src/components/admin/adminPanel.js b/src/components/admin/adminPanel.js old mode 100644 new mode 100755 diff --git a/src/components/chat/chatConnect.js b/src/components/chat/chatConnect.js new file mode 100755 index 0000000..0861e83 --- /dev/null +++ b/src/components/chat/chatConnect.js @@ -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 ( +
+ + +
+ ) + else + return ( +
+
+ Lobby: { chat.lobby } +
+ +
+ ) +} + +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) \ No newline at end of file diff --git a/src/components/chat/indexChat.js b/src/components/chat/indexChat.js new file mode 100755 index 0000000..d03c537 --- /dev/null +++ b/src/components/chat/indexChat.js @@ -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 ( +
+
setChatVisible( !chatVisible ) }> + chat +
+
+
+ +
+
+ { chat.host !== '' ? chat.messages.map( (message, key) => { + if ( chatImageVisible.visible ) + return ( +
setChatImageVisible( { visible: !chatImageVisible.visible, image: '' } ) }> + +
+ ) + if (message.userID === -1) + return ( +
+ ) + else if (message.userID === user.id) + return ( +
+
+ +
+
setChatImageVisible( { visible: !chatImageVisible.visible, image: message.image } ) : () => {} }> + { message.imageOnly === false ? +
+ {message.text} +
+ : +
+ } + { message.textOnly === false ? :
} +
+
+ ) + else + return ( +
+
+ +
+
setChatImageVisible( { visible: !chatImageVisible.visible, image: message.image } ) : () => {} }> + { message.imageOnly === false ? +
+ {message.text} +
+ : +
+ } + { message.textOnly === false ? :
} +
+
+ ) + } + ) + : ( chat.rooms.lenght === 0 ? + () => { + return ( +
+ Create first lobby! +
+ ) + } + : + chat.rooms.map( (room, key) => { + return ( +
+ { key + 1 }. Lobby: { room.name }, Users: { room.userCount } +
+ ) + } + ) + ) + } +
+
+
+ + + + +
+
+
+
+ ) +} + +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) \ No newline at end of file diff --git a/src/components/exchange/exchangeNotifications.js b/src/components/exchange/exchangeNotifications.js new file mode 100755 index 0000000..8f73a44 --- /dev/null +++ b/src/components/exchange/exchangeNotifications.js @@ -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 ( +
+

{ user.login } exchange notifications:

+
+ { exchange.userNotifications + .sort( (a, b) => b.id - a.id ) + .map( (notify, key) => { + return ( +
+

{ key + 1 }. { notify.message }

+ +
+ ) + } + ) + } +
+
+ ) +} + +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) diff --git a/src/components/exchange/exchangePrognosis.js b/src/components/exchange/exchangePrognosis.js new file mode 100755 index 0000000..6bb2f06 --- /dev/null +++ b/src/components/exchange/exchangePrognosis.js @@ -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 ( +
+ checkNewPrognosis() } + ref={ inputPrognosis }> + +

Forecast: { Number((exchange.prognosis.price_forecast).toFixed(2)) } PLN

+

Percent: { Number((exchange.prognosis.percent_of_difference).toFixed(3)) } %

+

Course on payment: { exchange.prognosis.course_on_payment } PLN

+

AVG: { Number((exchange.prognosis.svg_of_all).toFixed(2)) }

+

Date: { exchange.prognosis.date_of_transaction }

+
+ ) +} + +const mapStateToProps = state => ({ + user: state.user, + exchange: state.exchange +}) + +const mapDispatchToProps = dispatch => ({ + checkPrognosis: exchange => dispatch( checkPrognosis(exchange) ) +}) + +export default connect(mapStateToProps,mapDispatchToProps)(ExchangePrognosis) diff --git a/src/components/exchange/exchangeTriggerAdd.js b/src/components/exchange/exchangeTriggerAdd.js new file mode 100755 index 0000000..6ec8a3f --- /dev/null +++ b/src/components/exchange/exchangeTriggerAdd.js @@ -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 ( +
+
+

Trigger value: { triggerValue } zΕ‚

+ +
+

{ user.login } triggers:

+

{ message }

+
+ { exchange.userTriggers + .sort( (a, b) => b.id - a.id ) + .map( (trigger, key) => ( +
+

{ key + 1 }. Value: { trigger.course_values_for_trigger } PLN, Date: { trigger.date_of_trigger }, Status { trigger.status === 1 ? 'Enabled' : 'Disabled' }

+
+ ) ) } +
+
+ ) +} + +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) diff --git a/src/components/exchange/indexExchange.js b/src/components/exchange/indexExchange.js old mode 100644 new mode 100755 index f48e357..2136e15 --- a/src/components/exchange/indexExchange.js +++ b/src/components/exchange/indexExchange.js @@ -1,19 +1,177 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' 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 ( -
+
+
-1 ? 'exchangeChartUser' : 'exchangeChartGuest'}> +
getMousePosition(event)} + onClick={() => setTriggerValue(parseInt(cursorValue))} + style={{ width: exchange.candles.candlesCount * 15 + 'px' }}> + {user.id > -1 ? ( +
+
+

{parseInt(cursorValue)} PLN

+
+
+
+
+ ) : ( +
+ )} + {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 ( +
getCandleInformation(candle)}> + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+ ) + } + ) + } +
+
+
-1 ? 'exchangeInterface' : 'exchangeEmptySpace'}> +
+

Open: {candleInfo.Open} PLN

+

Close: {candleInfo.Close} PLN

+

Max: {candleInfo.Max} PLN

+

Min: {candleInfo.Min} PLN

+

Volume: {candleInfo.Vol}

+

Date: {candleInfo.Date}

+
+
+ {user.id > -1 ? ( +
+ + + +
+ ) : ( +
+ ) + }
) } + const mapStateToProps = state => ({ 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) diff --git a/src/components/forum/forumCommentUpdate.js b/src/components/forum/forumCommentUpdate.js old mode 100644 new mode 100755 index f2b2016..4cdf0fb --- a/src/components/forum/forumCommentUpdate.js +++ b/src/components/forum/forumCommentUpdate.js @@ -16,7 +16,15 @@ const ForumCommentUpdate = ({ 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() if ( updateCommentTextArea.current.value !== '' ) { let commentData = { @@ -25,7 +33,9 @@ const ForumCommentUpdate = ({ text: updateCommentTextArea.current.value } updateCommentTextArea.current.value = '' - updateComment(commentData) + await updateComment(commentData) + await sleep(100) + await refreshSubjectComments(subjectLoad) } } diff --git a/src/components/forum/forumComments.js b/src/components/forum/forumComments.js old mode 100644 new mode 100755 index 7df49d6..d6bbd5b --- a/src/components/forum/forumComments.js +++ b/src/components/forum/forumComments.js @@ -22,9 +22,16 @@ const ForumComments = ({ const [formDiv, setFormDiv] = useState(false) 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() if ( addCommentTextArea.current.value !== '' ) { let newComment = { @@ -34,25 +41,21 @@ const ForumComments = ({ token: user.token } addCommentTextArea.current.value = '' - addComment(newComment) + await addComment( newComment ) + await sleep(100) + await refreshSubjectComments(subjectLoad) setFormDiv( !formDiv ) - let actualSubject = { - id: subjects.actualSubjectID - } - refreshSubjectComments(actualSubject) } } - const deleteOldComment = (commentID) => { + const deleteOldComment = async(commentID) => { let delComment = { id: commentID, token: user.token } - deleteComment(delComment) - let actualSubject = { - id: subjects.actualSubjectID - } - refreshSubjectComments(actualSubject) + await deleteComment(delComment) + await sleep(100) + await refreshSubjectComments(subjectLoad) } const [commentText, setCommentText] = useState(0) diff --git a/src/components/forum/forumRatings.js b/src/components/forum/forumRatings.js old mode 100644 new mode 100755 index 53a3859..b8811bf --- a/src/components/forum/forumRatings.js +++ b/src/components/forum/forumRatings.js @@ -57,21 +57,22 @@ const ForumRatings = ({ let divYPositionOnPage = ratingDiv.getBoundingClientRect().top + 72 let yPosition = event.screenY - divYPositionOnPage - if ( yPosition > 200 ) { + if ( yPosition > 270 ) { setValue(5) } - else if ( yPosition > 150 && yPosition < 200 ) { + else if ( yPosition > 215 && yPosition < 270 ) { setValue(4) } - else if ( yPosition > 100 && yPosition < 150 ) { + else if ( yPosition > 168 && yPosition < 215 ) { setValue(3) } - else if ( yPosition > 50 && yPosition < 150 ) { + else if ( yPosition > 120 && yPosition < 168 ) { setValue(2) } - else if ( yPosition > 0 && yPosition < 50 ) { + else if ( yPosition > 60 && yPosition < 120 ) { setValue(1) } + console.log(yPosition) } const [updateRating, setUpdate] = useState(false) diff --git a/src/components/forum/forumSubjectUpdate.js b/src/components/forum/forumSubjectUpdate.js index 1d20122..db87bc0 100644 --- a/src/components/forum/forumSubjectUpdate.js +++ b/src/components/forum/forumSubjectUpdate.js @@ -17,6 +17,7 @@ const ForumSubjectUpdate = ({ const updateSubjectTitle = React.createRef() const updateSubjectAuthor = React.createRef() +<<<<<<< HEAD const updateOldSubject = (event) => { event.preventDefault() if ( updateSubjectTitle.current.value !== '') { @@ -25,6 +26,29 @@ const ForumSubjectUpdate = ({ name: updateSubjectTitle.current.value, user_id: user.id, 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 } updateSubject(putSubject) @@ -51,8 +75,13 @@ const ForumSubjectUpdate = ({
setTitleText(e.target.value.length) }> + +

Title: {titleText}/30

+ + +
- Foot + { user.privilige === 3 ? ( + + ) : ( +
+ ) }
@@ -64,8 +142,10 @@ const mapStateToProps = state => ({ }) const mapDispatchToProps = dispatch => ({ + addThread: threads => dispatch( addThread(threads) ), + deleteThread: threads => dispatch( deleteThread(threads) ), getAllThreads: () => dispatch( getAllThreads() ), - getThreadSubjects: thread => dispatch( getThreadSubjects(thread) ) + getThreadSubjects: threads => dispatch( getThreadSubjects(threads) ) }) export default connect(mapStateToProps, mapDispatchToProps)(IndexForum) diff --git a/src/components/forum/indexForumUpdate.js b/src/components/forum/indexForumUpdate.js new file mode 100755 index 0000000..b6d3b08 --- /dev/null +++ b/src/components/forum/indexForumUpdate.js @@ -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 ( +
+
+ setThreadTitleText( e.target.value.length ) }> + + { (user.privilige === 3) ? ( +
+ +
+ ) : ( +
+ ) + } +

{threadTitleText}/30

+ +
+
+ ) + } else { + return ( +
+
+ ) + } +} + +const mapStateToProps = state => ({ + user: state.user, + threads: state.threads +}) + +const mapDispatchToProps = dispatch => ({ + updateThread: threads => dispatch( updateThread(threads) ) +}) + +export default connect(mapStateToProps, mapDispatchToProps)(IndexForumUpdate) diff --git a/src/components/index.js b/src/components/index.js deleted file mode 100644 index ab85c78..0000000 --- a/src/components/index.js +++ /dev/null @@ -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 -} - - // 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) diff --git a/src/components/indexForm.js b/src/components/indexForm.js deleted file mode 100644 index ac43755..0000000 --- a/src/components/indexForm.js +++ /dev/null @@ -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 ( -
- - -
- ) -} - -const mapDispatchToProps = dispatch => ({ - add: subject => dispatch(actions.add(subject)) -}) - -export default connect(null, mapDispatchToProps)(IndexForm) diff --git a/src/components/indexInterface.js b/src/components/indexInterface.js old mode 100644 new mode 100755 index 75f120f..ebf48a6 --- a/src/components/indexInterface.js +++ b/src/components/indexInterface.js @@ -1,9 +1,10 @@ -import React from 'react' +import React, {useEffect} from 'react' import { connect } from 'react-redux' // Operations Redux import { createSession, deleteSession, updateSession, registerUser } from '../stores/user/duck/operations' +import { getChart } from '../stores/exchange/duck/operations' // Actions Redux @@ -16,6 +17,7 @@ import '../styles/index.scss' // Components import MenuBar from './menuBar/menuBar' +import Chat from './chat/indexChat' import Exchange from './exchange/indexExchange' import Forum from './forum/indexForum' @@ -28,9 +30,12 @@ import BtcLogo from '../images/BtcLogo.png' import ForumLogo from '../images/ForumLogo.png' const IndexInterface = ({ - user, movements, + user, movements, exchange, createSession, deleteSession, updateSession, registerUser, - setRegister, setEdit, setForum, setExchange, setAdminPanel, resetMovements}) => { + setRegister, setEdit, setForum, setExchange, setAdminPanel, resetMovements, + getChart }) => { + + useEffect( () => { getChart() }, [] ) const loginInput = React.createRef() const passwordInput = React.createRef() @@ -235,6 +240,45 @@ const IndexInterface = ({ } else if (user.privilige === 3) { return ( +
+
+ +
+
setExchange() }> + +
+
setForum() }> + +
+
+
+

Welcome

+

{user.login}

+
+
+ + +
+ +
+
+
+
+ +
+ ) + } + else { + return ( +
- ) - } - else { - return ( -
- -
-
setExchange() }> - -
-
setForum() }> - -
-
- -

Welcome

-

{user.login}

-
- - -
- -
-
-
+
) } @@ -304,6 +315,7 @@ const IndexInterface = ({ const mapStateToProps = state => ({ user: state.user, + exchange: state.exchange, movements: state.movements }) @@ -318,7 +330,9 @@ const mapDispatchToProps = dispatch => ({ setExchange: movements => dispatch( actions.exchange() ), setForum: movements => dispatch( actions.forum() ), 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) diff --git a/src/components/menuBar/menuBar.js b/src/components/menuBar/menuBar.js old mode 100644 new mode 100755 diff --git a/src/components/useInterval.js b/src/components/useInterval.js new file mode 100755 index 0000000..324d354 --- /dev/null +++ b/src/components/useInterval.js @@ -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 diff --git a/src/images/BtcLogo.png b/src/images/BtcLogo.png new file mode 100755 index 0000000..d452a4b Binary files /dev/null and b/src/images/BtcLogo.png differ diff --git a/src/images/ForumLogo.png b/src/images/ForumLogo.png new file mode 100755 index 0000000..8a47004 Binary files /dev/null and b/src/images/ForumLogo.png differ diff --git a/src/images/gatsby-astronaut.png b/src/images/gatsby-astronaut.png new file mode 100755 index 0000000..da58ece Binary files /dev/null and b/src/images/gatsby-astronaut.png differ diff --git a/src/images/gatsby-icon.png b/src/images/gatsby-icon.png new file mode 100755 index 0000000..908bc78 Binary files /dev/null and b/src/images/gatsby-icon.png differ diff --git a/src/images/stockExchange.mp4 b/src/images/stockExchange.mp4 new file mode 100755 index 0000000..c54d084 Binary files /dev/null and b/src/images/stockExchange.mp4 differ diff --git a/src/pages/index.js b/src/pages/index.js old mode 100644 new mode 100755 index dcb7e73..8002010 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -2,13 +2,13 @@ import React from "react"; import IndexInterface from "../components/indexInterface" -import store from "../stores/store"; +import { store } from "../stores/store"; import { Provider } from "react-redux"; import '../styles/general.scss' const IndexPage = () => ( - + ) diff --git a/src/stores/apiAddress.js b/src/stores/apiAddress.js new file mode 100755 index 0000000..e1a8ee1 --- /dev/null +++ b/src/stores/apiAddress.js @@ -0,0 +1,2 @@ +export const address = 'http://localhost:9090'//'http://tbs093a.pythonanywhere.com' +export const webSocketAddress = 'ws://localhost:9090/ws/' \ No newline at end of file diff --git a/src/stores/chat/duck/actions.js b/src/stores/chat/duck/actions.js new file mode 100755 index 0000000..900265e --- /dev/null +++ b/src/stores/chat/duck/actions.js @@ -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 +} \ No newline at end of file diff --git a/src/stores/chat/duck/index.js b/src/stores/chat/duck/index.js new file mode 100755 index 0000000..9aaeacf --- /dev/null +++ b/src/stores/chat/duck/index.js @@ -0,0 +1,5 @@ +import chatReducer from './reducers' +export { default as chatTypes } from './types' +export { default as chatActions } from './actions' + +export default chatReducer \ No newline at end of file diff --git a/src/stores/chat/duck/operations.js b/src/stores/chat/duck/operations.js new file mode 100755 index 0000000..1976bf3 --- /dev/null +++ b/src/stores/chat/duck/operations.js @@ -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)) +} \ No newline at end of file diff --git a/src/stores/chat/duck/reducers.js b/src/stores/chat/duck/reducers.js new file mode 100755 index 0000000..aeb1fc2 --- /dev/null +++ b/src/stores/chat/duck/reducers.js @@ -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 \ No newline at end of file diff --git a/src/stores/chat/duck/types.js b/src/stores/chat/duck/types.js new file mode 100755 index 0000000..8f0a4a5 --- /dev/null +++ b/src/stores/chat/duck/types.js @@ -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 +} \ No newline at end of file diff --git a/src/stores/comments/duck/actions.js b/src/stores/comments/duck/actions.js old mode 100644 new mode 100755 index 7de1f42..bb2970b --- a/src/stores/comments/duck/actions.js +++ b/src/stores/comments/duck/actions.js @@ -4,6 +4,11 @@ const getRatingsComment = item => ({ type: types.GET_COMMENTS_RATINGS, item }) +const addComment = item => ({ + type: types.ADD_COMMENT, item +}) + export default { - getRatingsComment + getRatingsComment, + addComment } diff --git a/src/stores/comments/duck/index.js b/src/stores/comments/duck/index.js old mode 100644 new mode 100755 diff --git a/src/stores/comments/duck/operations.js b/src/stores/comments/duck/operations.js old mode 100644 new mode 100755 index 0bbb4c7..5990f7d --- a/src/stores/comments/duck/operations.js +++ b/src/stores/comments/duck/operations.js @@ -1,8 +1,9 @@ import actions from './actions' +import { address } from './../../apiAddress' const fetchRatingsComment = async (comment) => { const response = await - fetch ('http://localhost:8001/index/comment/' + comment.id + '/rating', { + fetch (address + '/index/comment/' + comment.id + '/rating', { method: 'GET', credentials: 'same-origin' }); @@ -10,7 +11,7 @@ const fetchRatingsComment = async (comment) => { } const fetchAddRating = async (data) => { - fetch ('http://localhost:8001/index/comment/' + data.comment_id + '/rating', { + fetch (address + '/index/comment/' + data.comment_id + '/rating', { method: 'POST', credentials: 'same-origin', body: JSON.stringify(data) @@ -18,7 +19,7 @@ const fetchAddRating = async (data) => { } const fetchUpdateRating = async (rating) => { - fetch ('http://localhost:8001/index/rating/' + rating.id, { + fetch (address + '/index/rating/' + rating.id, { method: 'PUT', credentials: 'same-origin', body: JSON.stringify(rating) @@ -48,7 +49,7 @@ export const updateRatingComment = (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', credentials: 'same-origin', body: JSON.stringify(data) @@ -56,7 +57,7 @@ const fetchAddComment = async (data) => { } const fetchUpdateComment = async (data) => { - fetch ('http://localhost:8001/index/comment/' + data.id, { + fetch (address + '/index/comment/' + data.id, { method: 'PUT', credentials: 'same-origin', body: JSON.stringify(data) @@ -64,7 +65,7 @@ const fetchUpdateComment = async (data) => { } const fetchDeleteComment = async (data) => { - fetch ('http://localhost:8001/index/comment/' + data.id, { + fetch (address + '/index/comment/' + data.id, { method: 'Delete', credentials: 'same-origin', body: JSON.stringify(data) diff --git a/src/stores/comments/duck/reducers.js b/src/stores/comments/duck/reducers.js old mode 100644 new mode 100755 diff --git a/src/stores/comments/duck/types.js b/src/stores/comments/duck/types.js old mode 100644 new mode 100755 index 66e1543..d9e6432 --- a/src/stores/comments/duck/types.js +++ b/src/stores/comments/duck/types.js @@ -1,5 +1,7 @@ const GET_COMMENTS_RATINGS = 'GET_COMMENTS_RATINGS' +const ADD_COMMENT = 'ADD_COMMENT' export default { - GET_COMMENTS_RATINGS + GET_COMMENTS_RATINGS, + ADD_COMMENT } diff --git a/src/stores/exchange/duck/actions.js b/src/stores/exchange/duck/actions.js new file mode 100755 index 0000000..9ab2402 --- /dev/null +++ b/src/stores/exchange/duck/actions.js @@ -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 +} diff --git a/src/stores/exchange/duck/index.js b/src/stores/exchange/duck/index.js new file mode 100755 index 0000000..0a0cfe8 --- /dev/null +++ b/src/stores/exchange/duck/index.js @@ -0,0 +1,5 @@ +import exchangeReducer from './reducers' +export { default as exchangeTypes } from './types' +export { default as exchangeActions } from './actions' + +export default exchangeReducer diff --git a/src/stores/exchange/duck/operations.js b/src/stores/exchange/duck/operations.js new file mode 100755 index 0000000..1eccccf --- /dev/null +++ b/src/stores/exchange/duck/operations.js @@ -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) + } diff --git a/src/stores/exchange/duck/reducers.js b/src/stores/exchange/duck/reducers.js new file mode 100755 index 0000000..911fd32 --- /dev/null +++ b/src/stores/exchange/duck/reducers.js @@ -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 diff --git a/src/stores/exchange/duck/types.js b/src/stores/exchange/duck/types.js new file mode 100755 index 0000000..c32669c --- /dev/null +++ b/src/stores/exchange/duck/types.js @@ -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 +} diff --git a/src/stores/localStorage.js b/src/stores/localStorage.js new file mode 100755 index 0000000..220e3b2 --- /dev/null +++ b/src/stores/localStorage.js @@ -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'); + } + }; \ No newline at end of file diff --git a/src/stores/movements/duck/actions.js b/src/stores/movements/duck/actions.js old mode 100644 new mode 100755 diff --git a/src/stores/movements/duck/index.js b/src/stores/movements/duck/index.js old mode 100644 new mode 100755 diff --git a/src/stores/movements/duck/reducers.js b/src/stores/movements/duck/reducers.js old mode 100644 new mode 100755 diff --git a/src/stores/movements/duck/types.js b/src/stores/movements/duck/types.js old mode 100644 new mode 100755 diff --git a/src/stores/reducers.js b/src/stores/reducers.js old mode 100644 new mode 100755 index b510d9b..22c57c3 --- a/src/stores/reducers.js +++ b/src/stores/reducers.js @@ -1,16 +1,23 @@ import { combineReducers } from 'redux' + import movementsReducer from './movements/duck' import commentReducer from './comments/duck' import subjectReducer from './subjects/duck' import threadReducer from './threads/duck' + import userReducer from './user/duck' +import chatReducer from './chat/duck' + +import exchangeReducer from './exchange/duck' const rootReducer = combineReducers({ user: userReducer, + chat: chatReducer, threads: threadReducer, subjects: subjectReducer, comments: commentReducer, - movements: movementsReducer + movements: movementsReducer, + exchange: exchangeReducer }) export default rootReducer diff --git a/src/stores/store.js b/src/stores/store.js old mode 100644 new mode 100755 index 12cc1d7..86ef929 --- a/src/stores/store.js +++ b/src/stores/store.js @@ -1,10 +1,42 @@ import { createStore, applyMiddleware } from 'redux' import { composeWithDevTools } from 'redux-devtools-extension' -import rootReducer from './reducers' 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) +} diff --git a/src/stores/subjects/duck/actions.js b/src/stores/subjects/duck/actions.js old mode 100644 new mode 100755 index 43b9dc7..339b6c8 --- a/src/stores/subjects/duck/actions.js +++ b/src/stores/subjects/duck/actions.js @@ -12,8 +12,13 @@ const deactivate = item => ({ type: types.DEACTIVATE, item }) +const addComment = item => ({ + type: types.ADD_COMMENT, item +}) + export default { getSubjectComments, activate, - deactivate + deactivate, + addComment } diff --git a/src/stores/subjects/duck/index.js b/src/stores/subjects/duck/index.js old mode 100644 new mode 100755 diff --git a/src/stores/subjects/duck/operations.js b/src/stores/subjects/duck/operations.js old mode 100644 new mode 100755 index 9e456ff..90b24e1 --- a/src/stores/subjects/duck/operations.js +++ b/src/stores/subjects/duck/operations.js @@ -1,8 +1,9 @@ import actions from './actions' +import { address } from './../../apiAddress' const fetchSubjectComments = async (subject) => { const response = await - fetch('http://localhost:8001/index/subject/' + subject.id + '/comment', { + fetch(address + '/index/subject/' + subject.id + '/comment', { method: 'GET', credentials: 'same-origin' }); @@ -24,7 +25,7 @@ export const getSubjectComments = (data) => const fetchAddSubject = async (data) => { const response = await - fetch('http://localhost:8001/index/thread/' + data.thread_id + '/subject', { + fetch(address + '/index/thread/' + data.thread_id + '/subject', { method: 'POST', credentials: 'same-origin', body: JSON.stringify(data) @@ -39,7 +40,7 @@ const fetchAddSubject = async (data) => { const fetchPutSubject = async (data) => { const response = await - fetch('http://localhost:8001/index/subject/' + data.id, { + fetch(address + '/index/subject/' + data.id, { method: 'PUT', credentials: 'same-origin', body: JSON.stringify(data) @@ -54,7 +55,7 @@ const fetchPutSubject = async (data) => { const fetchDeleteSubject = async (data) => { const response = await - fetch('http://localhost:8001/index/subject/' + data.id, { + fetch(address + '/index/subject/' + data.subject_id, { method: 'DELETE', credentials: 'same-origin', body: JSON.stringify(data) diff --git a/src/stores/subjects/duck/reducers.js b/src/stores/subjects/duck/reducers.js old mode 100644 new mode 100755 index f58292e..d2be0c6 --- a/src/stores/subjects/duck/reducers.js +++ b/src/stores/subjects/duck/reducers.js @@ -34,6 +34,11 @@ const subjectReducer = (state = INITIAL_STATE, action) => { actualSubjectAuthorID: -1, isActive: false } + case types.ADD_COMMENT: + return { + ...state, + commentsList: [...state.commentsList, action.item] + } default: return state; } diff --git a/src/stores/subjects/duck/types.js b/src/stores/subjects/duck/types.js old mode 100644 new mode 100755 index d6ce16d..c78a40b --- a/src/stores/subjects/duck/types.js +++ b/src/stores/subjects/duck/types.js @@ -1,9 +1,11 @@ const GET_SUBJECT_COMMENTS = 'GET_SUBJECT_COMMENTS' const ACTIVATE = 'ACTIVATE' const DEACTIVATE = 'DEACTIVATE' +const ADD_COMMENT = 'ADD_COMMENT' export default{ GET_SUBJECT_COMMENTS, ACTIVATE, - DEACTIVATE + DEACTIVATE, + ADD_COMMENT } diff --git a/src/stores/threads/duck/actions.js b/src/stores/threads/duck/actions.js old mode 100644 new mode 100755 diff --git a/src/stores/threads/duck/index.js b/src/stores/threads/duck/index.js old mode 100644 new mode 100755 diff --git a/src/stores/threads/duck/operations.js b/src/stores/threads/duck/operations.js old mode 100644 new mode 100755 index cd882a5..2af50b8 --- a/src/stores/threads/duck/operations.js +++ b/src/stores/threads/duck/operations.js @@ -1,9 +1,10 @@ import actions from './actions' +import { address } from './../../apiAddress' const fetchGetAll = async () => { const response = await fetch ( - 'http://localhost:8001/index/thread', { + address + '/index/thread', { method: 'GET', credential: 'same-origin' } @@ -14,7 +15,7 @@ const fetchGetAll = async () => { const fetchGetSubjects = async (threadID) => { const response = await fetch( - 'http://localhost:8001/index/thread/' + threadID + '/subject', { + address + '/index/thread/' + threadID + '/subject', { method: 'GET', credential: 'same-origin' } @@ -22,6 +23,43 @@ const fetchGetSubjects = async (threadID) => { 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 = () => async (dispatch) => { const allThreads = await fetchGetAll() @@ -41,3 +79,18 @@ export const getThreadSubjects = (data) => dispatch( actions.activate(data) ) 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) + } diff --git a/src/stores/threads/duck/reducers.js b/src/stores/threads/duck/reducers.js old mode 100644 new mode 100755 diff --git a/src/stores/threads/duck/types.js b/src/stores/threads/duck/types.js old mode 100644 new mode 100755 diff --git a/src/stores/user/duck/actions.js b/src/stores/user/duck/actions.js old mode 100644 new mode 100755 diff --git a/src/stores/user/duck/index.js b/src/stores/user/duck/index.js old mode 100644 new mode 100755 diff --git a/src/stores/user/duck/operations.js b/src/stores/user/duck/operations.js old mode 100644 new mode 100755 index aa0ccc5..0e9f084 --- a/src/stores/user/duck/operations.js +++ b/src/stores/user/duck/operations.js @@ -1,11 +1,12 @@ import actions from './actions' +import { address } from './../../apiAddress' var jwtDecode = require('jwt-decode') const fetchLogin = async (user) => { const response = await fetch ( - 'http://localhost:8001/index/authUser', { + address + '/index/authUser', { method: 'POST', credential: 'same-origin', body: JSON.stringify(user), @@ -16,7 +17,7 @@ const fetchLogin = async (user) => { const fetchLogout = async (userToken) => { fetch ( - 'http://localhost:8001/index/authUser', { + address + '/index/authUser', { method: 'DELETE', credential: 'same-origin', body: JSON.stringify(userToken), @@ -26,7 +27,7 @@ const fetchLogout = async (userToken) => { const fetchUpdate = async (user) => { fetch ( - 'http://localhost:8001/index/user/' + user.id, { + address + '/index/user/' + user.id, { method: 'PUT', credential: 'same-origin', body: JSON.stringify(user), @@ -35,7 +36,7 @@ const fetchUpdate = async (user) => { const fetchRegister = async (user) => { fetch ( - 'http://localhost:8001/index/user', { + address + '/index/user', { method: 'POST', credential: 'same-origin', body: JSON.stringify(user), @@ -46,12 +47,12 @@ const fetchRegister = async (user) => { const fetchGetAllUsers = async () => { const response = await fetch ( - 'http://localhost:8001/index/user', { + address + '/index/user', { method: 'GET', credential: 'same-origin' } ) - const json = await response.json() + const json = response.json() return json } @@ -61,9 +62,7 @@ export const createSession = (data) => const token = await fetchLogin(data) let user = jwtDecode(token.token) - let allUsers = 'None' - if ( user.payload.privilige > 1 ) - allUsers = await fetchGetAllUsers() + let allUsers = await fetchGetAllUsers() let userFull = { token: token.token, @@ -79,7 +78,7 @@ export const createSession = (data) => } export const updateSession = (data) => - async (dispatch) => { + async () => { await fetchUpdate(data) } @@ -90,6 +89,6 @@ export const deleteSession = (data) => } export const registerUser = (data) => - async (dispatch) => { + async () => { await fetchRegister(data) } diff --git a/src/stores/user/duck/reducers.js b/src/stores/user/duck/reducers.js old mode 100644 new mode 100755 index f72f3e1..1596141 --- a/src/stores/user/duck/reducers.js +++ b/src/stores/user/duck/reducers.js @@ -7,7 +7,8 @@ const INITIAL_STATE = { privilige: '', avatar: '', token: '', - isActive: false + isActive: false, + allUsersList: [] } const userReducer = (state = INITIAL_STATE, action) => { @@ -20,11 +21,12 @@ const userReducer = (state = INITIAL_STATE, action) => { email: action.item.email, avatar: action.item.avatar, token: action.item.token, - isActive: true, - allUsersList: action.item.allUsersList + allUsersList: action.item.allUsersList, + isActive: true } case types.LOGOUT_USER: return { + id: -1, isActive: false } default: diff --git a/src/stores/user/duck/types.js b/src/stores/user/duck/types.js old mode 100644 new mode 100755 diff --git a/src/styles/elements.scss b/src/styles/elements.scss old mode 100644 new mode 100755 index 1798473..3353b84 --- a/src/styles/elements.scss +++ b/src/styles/elements.scss @@ -5,6 +5,12 @@ margin: auto; } +@mixin scrollStyle { + width: 10px; + height: 10px; + background-color: rgba(22,28,29,0.5); +} + @mixin inputStyle { width: 200px; height: 35px; @@ -26,7 +32,7 @@ border: 0px; border-radius: 10px; 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); transition-duration: 0.5s; @@ -41,14 +47,21 @@ } } +@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,700); + @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; margin-top: 0; 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); border-bottom: 1px solid; border-color: rgba(117,82,29,0.7); @@ -89,3 +102,28 @@ rgba(9,17,121,0.1) 10%, 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%; + } +} diff --git a/src/styles/forumRatings.scss b/src/styles/forumRatings.scss old mode 100644 new mode 100755 index 7ef130d..d5f87f9 --- a/src/styles/forumRatings.scss +++ b/src/styles/forumRatings.scss @@ -14,11 +14,14 @@ $widthRT: 40px; width: 1px; height: 250px; - background-color: rgba(117,82,29,1); + border: solid 1px; + border-color: rgba(117,82,29,1); margin: auto; } .ratingValue { + width: $widthRT; + height: 250px; transition-duration: 0.5s; } diff --git a/src/styles/general.scss b/src/styles/general.scss old mode 100644 new mode 100755 index b5fe1a1..a19b076 --- a/src/styles/general.scss +++ b/src/styles/general.scss @@ -2,7 +2,11 @@ body { margin: 0 auto; + overflow-y: hidden; + ::-webkit-scrollbar { + @include scrollStyle + } input { @include inputStyle } diff --git a/src/styles/index.scss b/src/styles/index.scss old mode 100644 new mode 100755 index 9ec59e0..1d6f90c --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -28,10 +28,10 @@ margin-right: auto; margin-left: auto; - @include BigButtonStyle + @include BigButtonStyle; input { - @include inputStyle + @include inputStyle; width: 100%; } diff --git a/src/styles/indexChat.scss b/src/styles/indexChat.scss new file mode 100755 index 0000000..3ea76bc --- /dev/null +++ b/src/styles/indexChat.scss @@ -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; + } +} \ No newline at end of file diff --git a/src/styles/indexExchange.scss b/src/styles/indexExchange.scss new file mode 100755 index 0000000..a4b16a1 --- /dev/null +++ b/src/styles/indexExchange.scss @@ -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; + } + } + +} diff --git a/src/styles/indexForum.scss b/src/styles/indexForum.scss old mode 100644 new mode 100755 index 7549326..b78ac10 --- a/src/styles/indexForum.scss +++ b/src/styles/indexForum.scss @@ -6,7 +6,7 @@ } .indexForum { - @include backgroundDefaultDivStyle + @include backgroundDefaultDivStyle; position: relative; z-index: 0; @@ -48,8 +48,8 @@ } .forumTitle { - @include forumDiv - @include gapTopBetweenElements + @include forumDiv; + @include gapTopBetweenElements; p { font-size: 50px; float: left; @@ -75,7 +75,7 @@ } .forumItemsList { - @include gapTopBetweenElements + @include gapTopBetweenElements; .forumListItem:last-child{ border-bottom: 0px dashed; @@ -88,7 +88,7 @@ padding-left: 5%; padding-top: 15px; - @include gapBetweenItems + @include gapBetweenItems; p:first-child { font-size: 30px; @@ -99,7 +99,8 @@ float: right; text-align: right; padding-top: 10px; - min-width: 130px; + min-width: 120px; + text-align: right; } @@ -135,7 +136,7 @@ transition-duration: 0.5s; display: flex; - @include gapBetweenItems + @include gapBetweenItems; &:last-child{ border-bottom: 1px; @@ -147,7 +148,7 @@ padding: 50px; padding-bottom: 30px; text-align: center; - @include gapBetweenSections + @include gapBetweenSections; img { width: 200px; @@ -166,7 +167,7 @@ word-wrap: break-word; - @include gapBetweenSections + @include gapBetweenSections; } .commentRating { width: 15%; @@ -181,22 +182,26 @@ } .forumFormSubject { - @include forumDiv + @include forumDiv; height: auto; display: flex; transition-duration: 0.5s; - @include gapTopBetweenElements + @include gapTopBetweenElements; form { width: 100%; } - - input, select { + input { width: 100%; float: left; text-align: left; } + select { + width: 100%; + float: left; + + } textarea { width: 100%; height: 200px; @@ -213,13 +218,13 @@ } .forumFormComment { - @include forumDiv + @include forumDiv; height: auto; display: flex; transition-duration: 0.5s; - @include gapTopBetweenElements + @include gapTopBetweenElements; textarea { width: 100%; height: 200px; @@ -235,7 +240,7 @@ } .forumFoot { - @include forumDiv + @include forumDiv; button { float: right; } diff --git a/src/styles/menuBar.scss b/src/styles/menuBar.scss old mode 100644 new mode 100755