diff --git a/package-lock.json b/package-lock.json index e9c944fda0a8d846e5b09e5a784cf06ac33b77ef..4df1f226340ca1829bd92ec669533a220c134fdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1691,12 +1691,21 @@ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.6.tgz", "integrity": "sha512-Yp51mevbOEdxDUy5WjiKtpQaecqYq9OqZSL04rSoCiry7Tc5I9FEyo3bfxiTJc1DfHeKwSFCUYbBAiOQ2VGfiw==", "requires": { +<<<<<<< HEAD + "browserslist": "^4.3.7", + "caniuse-lite": "^1.0.30000926", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.7", + "postcss-value-parser": "^3.3.1" +======= "browserslist": "4.4.1", "caniuse-lite": "1.0.30000932", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "7.0.14", "postcss-value-parser": "3.3.1" +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 }, "dependencies": { "chalk": { @@ -2520,9 +2529,15 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", "requires": { +<<<<<<< HEAD + "caniuse-lite": "^1.0.30000925", + "electron-to-chromium": "^1.3.96", + "node-releases": "^1.1.3" +======= "caniuse-lite": "1.0.30000932", "electron-to-chromium": "1.3.108", "node-releases": "1.1.3" +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 } }, "bser": { @@ -12226,10 +12241,23 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", "requires": { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "define-properties": "1.1.3", "es-abstract": "1.12.0", "function-bind": "1.1.1", "has": "1.0.3" +<<<<<<< HEAD +======= + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" +>>>>>>> changes +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 } }, "obuf": { @@ -16367,7 +16395,15 @@ "loader-utils": "1.1.0", "opn": "5.4.0", "pkg-up": "2.0.0", +<<<<<<< HEAD +<<<<<<< HEAD + "react-error-overlay": "5.1.1", +======= + "react-error-overlay": "^5.1.2", +>>>>>>> changes +======= "react-error-overlay": "5.1.2", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "recursive-readdir": "2.2.2", "shell-quote": "1.6.1", "sockjs-client": "1.1.5", @@ -16593,8 +16629,18 @@ "postcss-loader": "3.0.0", "postcss-preset-env": "6.3.1", "postcss-safe-parser": "4.0.1", +<<<<<<< HEAD +<<<<<<< HEAD + "react-app-polyfill": "0.2.0", + "react-dev-utils": "7.0.0", +======= + "react-app-polyfill": "^0.2.0", + "react-dev-utils": "^7.0.1", +>>>>>>> changes +======= "react-app-polyfill": "0.2.0", "react-dev-utils": "7.0.1", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "resolve": "1.8.1", "sass-loader": "7.1.0", "style-loader": "0.23.0", @@ -16604,6 +16650,112 @@ "webpack-dev-server": "3.1.14", "webpack-manifest-plugin": "2.0.4", "workbox-webpack-plugin": "3.6.3" +<<<<<<< HEAD +<<<<<<< HEAD + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "eslint": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.0.tgz", + "integrity": "sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA==", + "requires": { + "@babel/code-frame": "7.0.0", + "ajv": "6.6.2", + "chalk": "2.4.1", + "cross-spawn": "6.0.5", + "debug": "3.1.0", + "doctrine": "2.1.0", + "eslint-scope": "4.0.0", + "eslint-utils": "1.3.1", + "eslint-visitor-keys": "1.0.0", + "espree": "4.1.0", + "esquery": "1.0.1", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.3", + "globals": "11.9.0", + "ignore": "4.0.6", + "imurmurhash": "0.1.4", + "inquirer": "6.2.1", + "is-resolvable": "1.1.0", + "js-yaml": "3.12.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.3", + "regexpp": "2.0.1", + "require-uncached": "1.0.3", + "semver": "5.6.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.3", + "text-table": "0.2.0" + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "requires": { + "esrecurse": "4.2.1", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "requires": { + "acorn": "6.0.4", + "acorn-jsx": "5.0.1", + "eslint-visitor-keys": "1.0.0" + } + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + }, + "table": { + "version": "4.0.3", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "requires": { + "ajv": "6.6.2", + "ajv-keywords": "3.2.0", + "chalk": "2.4.1", + "lodash": "4.17.11", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + } +======= +>>>>>>> changes +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 } }, "react-slick": { @@ -17764,14 +17916,34 @@ } }, "semantic-ui-calendar-react": { +<<<<<<< HEAD +<<<<<<< HEAD + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/semantic-ui-calendar-react/-/semantic-ui-calendar-react-0.13.0.tgz", + "integrity": "sha512-+DhCcj2GZBQspW2dY8Q0rKL4a1u9bCb1XP138KXbl23ZPRWbLK9+gHbbnL1fs3VlLjwoKMBaZGUs80gbGIN1CQ==", +======= "version": "0.12.2", "resolved": "https://registry.npmjs.org/semantic-ui-calendar-react/-/semantic-ui-calendar-react-0.12.2.tgz", "integrity": "sha512-XK7Mda6x7YNGC68S/1bCNtOuky3YV0Qn8+on+g8VQ1wuBXQRHQxC1d7NbYaHG7k9eYL5FywLYz4Y1m+oOtpo8A==", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "requires": { "keyboard-key": "1.0.2", "lodash": "4.17.11", "moment": "2.23.0", "prop-types": "15.6.2" +<<<<<<< HEAD +======= + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/semantic-ui-calendar-react/-/semantic-ui-calendar-react-0.12.2.tgz", + "integrity": "sha512-XK7Mda6x7YNGC68S/1bCNtOuky3YV0Qn8+on+g8VQ1wuBXQRHQxC1d7NbYaHG7k9eYL5FywLYz4Y1m+oOtpo8A==", + "requires": { + "keyboard-key": "^1.0.2", + "lodash": "^4.17.10", + "moment": "^2.22.2", + "prop-types": "^15.6.2" +>>>>>>> changes +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 } }, "semantic-ui-css": { @@ -18234,11 +18406,28 @@ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", "requires": { +<<<<<<< HEAD +<<<<<<< HEAD + "debug": "2.6.9", + "handle-thing": "1.2.5", +======= "debug": "4.1.1", "handle-thing": "2.0.0", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "http-deceiver": "1.2.7", "select-hose": "2.0.0", +<<<<<<< HEAD + "spdy-transport": "2.1.1" +======= + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" +>>>>>>> changes +======= "spdy-transport": "3.0.0" +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 }, "dependencies": { "debug": { @@ -18261,12 +18450,28 @@ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "requires": { +<<<<<<< HEAD +<<<<<<< HEAD + "debug": "2.6.9", +======= "debug": "4.1.1", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "detect-node": "2.0.4", "hpack.js": "2.1.6", "obuf": "1.1.2", "readable-stream": "3.1.1", "wbuf": "1.7.3" +<<<<<<< HEAD +======= + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" +>>>>>>> changes +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 }, "dependencies": { "debug": { @@ -19754,6 +19959,10 @@ "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==", "requires": { "ansi-html": "0.0.7", +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "bonjour": "3.5.0", "chokidar": "2.0.4", "compression": "1.7.3", @@ -19779,7 +19988,38 @@ "spdy": "4.0.0", "strip-ansi": "3.0.1", "supports-color": "5.5.0", +<<<<<<< HEAD +======= + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "~0.18.0", + "import-local": "^2.0.0", + "internal-ip": "^3.0.1", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "schema-utils": "^1.0.0", + "selfsigned": "^1.9.1", + "semver": "^5.6.0", + "serve-index": "^1.7.2", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^5.1.0", + "url": "^0.11.0", +>>>>>>> changes +======= "url": "0.11.0", +>>>>>>> 4b5aacd74856967607084c19a9557f4c7030b3a2 "webpack-dev-middleware": "3.4.0", "webpack-log": "2.0.0", "yargs": "12.0.2" diff --git a/src/actions/auth.js b/src/actions/auth.js index 44a29921b6019ae93f5cc665743933d7f4934196..5b2a5b60b2f2edbee2ed412561779aec224cdbde 100644 --- a/src/actions/auth.js +++ b/src/actions/auth.js @@ -1,6 +1,6 @@ import axios from './session'; import { GET_USERDATA, PROFILE_CHANGE, GROUP_CHANGE } from './types'; - +import { showMessage } from './messages'; export const getUserData = () => ( async (dispatch) => { @@ -59,7 +59,7 @@ export const groupChange = groups => ( export const submitRegistration = ({ nick, groups, signed, motivationAbout, motivationProfession, motivationExercise, id, }) => ( - async () => { + async (dispatch) => { try { const response = await axios.patch(`/api/v1/profiles/${id}/`, { nick, @@ -70,12 +70,12 @@ export const submitRegistration = ({ motivation_exercise: motivationExercise, }); if (response.data.id === id) { - alert('Sikeres mentés!'); + dispatch(showMessage('Sikeres mentés!', 'success')); } else { - alert('Mentés nem sikerült!'); + dispatch(showMessage('A mentés nem sikerült!', 'error')); } } catch (e) { - console.log(e); + dispatch(showMessage('A mentés nem sikerült!', 'error')); } } ); diff --git a/src/actions/messages.js b/src/actions/messages.js new file mode 100644 index 0000000000000000000000000000000000000000..01dd9c515319ff8b9e747d50dc70f727c22c7ad8 --- /dev/null +++ b/src/actions/messages.js @@ -0,0 +1,11 @@ +import { SHOW_MESSAGE, DISMISS_MESSAGE } from '../actions/types'; + +export const dismissMessage = () => ( + (dispatch) => { + dispatch({ type: DISMISS_MESSAGE }); + } +); + +export const showMessage = (text, messageType) => ( + { type: SHOW_MESSAGE, messageType, text } +); diff --git a/src/actions/news.js b/src/actions/news.js index 0a953af5d51335bad8809c32f9eb2ad1c8d709e0..44fa2fddbab402d8192623fd61781cc517225266 100644 --- a/src/actions/news.js +++ b/src/actions/news.js @@ -1,6 +1,7 @@ import axios from './session'; import { GET_NEWS, WRITE_NEWS, ADD_NEWS, DELETE_NEWS, - CLEAR_WRITE, SELECT_NEWS, EDIT_NEWS } from './types'; + CLEAR_WRITE, SELECT_NEWS, EDIT_NEWS, SHOW_MESSAGE } from './types'; +import { showMessage } from './messages'; export const getNews = () => ( async (dispatch) => { @@ -25,16 +26,16 @@ export const postNews = ({ title, author, text }) => ( text, }); if (response.data.id) { - alert('Sikeres mentés!'); dispatch({ type: ADD_NEWS, payload: response.data, }); + dispatch(showMessage('HÃr hozzádva!', 'success')); } else { - alert('Mentés nem sikerült!'); + dispatch(showMessage('Nem sikerült a hÃrt hozáadni!', 'error')); } } catch (e) { - console.log(e); + dispatch(showMessage('Nem sikerült a hÃrt hozáadni!', 'error')); } } ); @@ -48,17 +49,17 @@ export const editNews = ({ id, title, editedBy, text }) => ( text, }); if (response.data.id) { - alert('Sikeres mentés!'); + dispatch(showMessage('HÃr módosÃtva!', 'success')); dispatch({ type: EDIT_NEWS, payload: response.data, }); } else { - alert('Mentés nem sikerült!'); + dispatch(showMessage('Nem sikerült a módosÃtás', 'error')); } } catch (e) { - console.log(e); + dispatch(showMessage('Nem sikerült a módosÃtás', 'error')); } } ); @@ -68,16 +69,16 @@ export const deleteNews = news => ( try { const response = await axios.delete(`/api/v1/news/${news.id}/`); if (!response.data.id) { - alert('Sikeres törlés!'); + dispatch(showMessage('Sikeres törlés!', 'success')); dispatch({ type: DELETE_NEWS, payload: news, }); } else { - alert('A törlés nem sikerült!'); + dispatch(showMessage('A törlés nem sikerült!', 'error')); } } catch (e) { - console.log(e); + dispatch(showMessage('A törlés nem sikerült!', 'error')); } }); diff --git a/src/actions/notes.js b/src/actions/notes.js index 4737c1f411186ebe3133de36ea78a62f3c2f311e..e51673fb4b092b325bf3e8865ec7ef407a41da19 100644 --- a/src/actions/notes.js +++ b/src/actions/notes.js @@ -5,7 +5,10 @@ import { ADD_EVENT_NOTE, CLEAR_WRITE, DELETE_NOTE, + GET_NOTES_BY_PROFILE, + ADD_PROFILE_NOTE, } from './types'; +import { showMessage } from './messages'; export const getNotesByEvent = id => ( async (dispatch) => { @@ -21,11 +24,25 @@ export const getNotesByEvent = id => ( } ); +export const getNotesByProfile = id => ( + async (dispatch) => { + try { + const response = await axios.get('/api/v1/notes/', { params: { profileID: id } }); + dispatch({ + type: GET_NOTES_BY_PROFILE, + payload: response.data, + }); + } catch (e) { + console.log(e); + } + } +); + export const writeNote = (event) => { return (dispatch => (dispatch({ type: WRITE_NOTE, payload: event.target.value }))); }; -export const postEventNote = ({ eventid, userid, note }) => ( +export const postNote = ({ eventid, userid, note }) => ( async (dispatch) => { try { const response = await axios.post('/api/v1/notes/', { @@ -34,14 +51,22 @@ export const postEventNote = ({ eventid, userid, note }) => ( note, }); if (response.data.id) { - alert('Sikeres mentés!'); - dispatch({ - type: ADD_EVENT_NOTE, - payload: response.data, - }); + dispatch(showMessage('A megjegyzés hozzáadva!', 'success')); + if (eventid) { + dispatch({ + type: ADD_EVENT_NOTE, + payload: response.data, + }); + } + if (userid) { + dispatch({ + type: ADD_PROFILE_NOTE, + payload: response.data, + }); + } } } catch (e) { - console.log(e); + dispatch(showMessage('A hozzáadás nem sikerült!', 'error')); } }); @@ -56,13 +81,13 @@ export const deleteNote = note => ( try { const response = await axios.delete(`/api/v1/notes/${note.id}/`); if (!response.data.id) { - alert('Sikeres törlés!'); + dispatch(showMessage('Sikeres törlés!', 'success')); dispatch({ type: DELETE_NOTE, payload: note, }); } else { - alert('A törlés nem sikerült!'); + dispatch(showMessage('A törlés nem sikerült!', 'error')); } } catch (e) { console.log(e); diff --git a/src/actions/statistics.js b/src/actions/statistics.js index 1f92b1e2e54fe6001ef4d8722dc34e18136a9acb..7f53e13aadaced9016dc5dbee4be753605ef8eef 100644 --- a/src/actions/statistics.js +++ b/src/actions/statistics.js @@ -16,6 +16,7 @@ import { WRITE_EDITED_EVENT, SELECT_EVENT_FOR_EDIT, } from './types'; +import { showMessage } from './messages'; export const getStaffEvents = () => ( async (dispatch) => { @@ -86,17 +87,17 @@ export const visitorChange = ({ id, value }) => { }; export const submitVisitors = ({ id, visitors, absent }) => ( - async () => { + async (dispatch) => { try { const response = await axios.patch(`/api/v1/staff_events/${id}/`, { visitors, absent, }); if (response.data.id) { - alert('Sikeres mentés!'); + dispatch(showMessage('Sikeres változtatás!', 'success')); } } catch (e) { - console.log(e); + dispatch(showMessage('Nem sikerült a változtatás!', 'error')); } } ); @@ -128,14 +129,14 @@ export const editEvent = ({ id, name, description, date }) => ( date, }); if (response.data.id) { - alert('Sikeres mentés!'); + dispatch(showMessage('Az alkalom módosÃtva!', 'success')); dispatch({ type: EDIT_EVENT, payload: response.data, }); } else { - alert('Mentés nem sikerült!'); + dispatch(showMessage('A módosÃtás nem sikerült!', 'error')); } } catch (e) { console.log(e); @@ -153,13 +154,13 @@ export const addEvent = ({ name, date, description }) => ( absent: [], }); if (response.data.id) { - alert('Sikeres mentés!'); + dispatch(showMessage('Az alkalom hozzáadva!', 'success')); dispatch({ type: ADD_EVENT, payload: response.data, }); } else { - alert('Mentés nem sikerült!'); + dispatch(showMessage('A hozzáadás nem sikerült!', 'error')); } } catch (e) { console.log(e); @@ -172,13 +173,13 @@ export const deleteEvent = event => ( try { const response = await axios.delete(`/api/v1/staff_events/${event.id}/`); if (!response.data.id) { - alert('Sikeres törlés!'); + dispatch(showMessage('Az alkalom törölve!', 'success')); dispatch({ type: DELETE_EVENT, payload: event, }); } else { - alert('A törlés nem sikerült!'); + dispatch(showMessage('A törlés nem sikerült!', 'error')); } } catch (e) { console.log(e); @@ -206,11 +207,15 @@ export const setStatus = (id, status) => ( role: status, }); if (response.data.id) { + dispatch(showMessage('Státusz megváltoztatva!', 'success')); dispatch({ type: SET_STATUS, payload: response.data, }); } + else { + dispatch(showMessage('A változtatás nem sikerült!', 'error')); + } } catch (e) { console.log(e); } diff --git a/src/actions/types.js b/src/actions/types.js index 8608715a4aeb89cf94a5b8549aceec236da05bc9..988caca73c58db433be777050d353e09136df680 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -31,8 +31,8 @@ export const GET_EVENTS = 'get_events'; export const GET_EVENT_BY_ID = 'get_event_by_id'; export const GET_TRAINEES = 'get_trainees'; -export const VISITOR_CHANGE = 'visitor_change'; export const ABSENT_CHANGE = 'absent_change'; +export const VISITOR_CHANGE = 'visitor_change'; export const CHANGE_NO = 'change_no'; export const GET_NOTES_BY_EVENT = 'get_notes_by_event'; @@ -47,7 +47,12 @@ export const WRITE_NOTE = 'write_note'; export const CLEAR_NOTE = 'clear_note'; export const ADD_EVENT_NOTE = 'add_note'; export const DELETE_NOTE = 'delete_note'; +export const ADD_PROFILE_NOTE = 'add_profile_note'; +export const GET_NOTES_BY_PROFILE = 'get_notes_by_profile'; export const GET_PROFILES = 'get_profiles'; export const SET_STATUS = 'set_status'; export const GET_SELECTED_PROFILE = 'get_selected_profile'; + +export const SHOW_MESSAGE = 'show_message'; +export const DISMISS_MESSAGE = 'dismiss_message'; diff --git a/src/components/AlertMessage.js b/src/components/AlertMessage.js new file mode 100644 index 0000000000000000000000000000000000000000..d11cdaa80393f5382680c6c070c4edfdb47c0b00 --- /dev/null +++ b/src/components/AlertMessage.js @@ -0,0 +1,75 @@ +import React, { Component } from 'react'; +import { Message, Container } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import { dismissMessage } from '../actions/messages'; + +const messages = [ + { + type: 'success', + icon: 'thumbs up', + title: 'Sikeres művelet', + success: true, + warning: false, + error: false, + }, + { + type: 'warning', + icon: 'warning', + title: 'Figyelmeztetés', + success: false, + warning: true, + error: false, + }, + { + type: 'error', + icon: 'times circle', + title: 'Sikertelen művelet', + success: false, + warning: false, + error: true, + }, +]; + +class AlertMessage extends Component { + constructor (props) { + super(props); + this.state = { + timeout: null, + } + } +componentWillReceiveProps() { + clearTimeout(this.state.timeout); + const time = setTimeout(() => { + this.props.dismissMessage(); + }, 4000); + this.setState({ timeout: time }); + } + + render() { + const { visible, messageType, text } = this.props.message; + const messageProps = messages.find(item => item.type === messageType); + return ( + <Container style={visible ? { padding: '1.5em', paddingBottom: '0.5em' } : { padding: '0em' }}> + { messageProps ? + <Message + icon={messageProps.icon} + visible={visible} + header={messageProps.title} + content={text} + positive={messageProps.success} + warning={messageProps.warning} + negative={messageProps.error} + /> + : + null + } + </Container> + ); + } +} + +const mapStateToProps = ({ message }) => ({ + message +}); + +export default connect(mapStateToProps, { dismissMessage })(AlertMessage) diff --git a/src/components/App.js b/src/components/App.js index 5f2030756636d673c6834b9f6ea3114df880c629..11d1171015f1b3147d65792d5092ff69bb7daa6f 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -2,15 +2,16 @@ import React from 'react'; import Header from './Header'; import Main from './Main'; import Footer from './Footer'; +import AlertMessage from './AlertMessage'; const App = () => ( <div style={{ minHeight: '100%', position: 'relative' }}> - <header id='header' > - <Header /> - </header> - <main id='main' style={{ minHeight: '100%', position: 'relative' }}> - <Main /> - </main> + <Header className='header'> + <main id='main' style={{ minHeight: '100%', position: 'relative' }}> + <AlertMessage /> + <Main /> + </main> + </Header> <footer id='footer' style={{ position: 'absolute', width: '100%', bottom: '0' }}> <Footer /> </footer> diff --git a/src/components/Header.css b/src/components/Header.css new file mode 100644 index 0000000000000000000000000000000000000000..b620d357e20471ab51c25937f4d4af34221b0559 --- /dev/null +++ b/src/components/Header.css @@ -0,0 +1,3 @@ +.menu-item { + align-self: center; +} diff --git a/src/components/Header.js b/src/components/Header.js index c27945d8c282f067cf1535d76aa49b54437864eb..a9aec4e8d9310437ab359368b656d195e84dcfaa 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,17 +1,18 @@ import React, { Component } from 'react'; -import { Link } from 'react-router-dom'; import { - Menu, - Container, - Button, - Segment, - Visibility, Image, + Responsive, + Sidebar, + Icon } from 'semantic-ui-react'; import { connect } from 'react-redux'; import { getUserData } from '../actions'; import KSZKlogo from './images/kszk_logo.svg'; +import MobileContainer from './menus/MobileContainer'; +import DesktopContainer from './menus/DesktopContainer'; + + const menuItems = [ { text: 'FÅ‘oldal', @@ -35,7 +36,7 @@ const menuItems = [ text: 'Ãœtemterv', to: '/schedule', prefix: '', - permissionLevel: 1, + permissionLevel: 2, }, { text: 'Statisztika', @@ -57,96 +58,12 @@ const menuItems = [ }, ]; -const FixedMenu = ({ user }) => ( - <Menu fixed='top' size='large' pointing> - <Container> - {menuItems.map((item, i) => - (user.permission >= item.permissionLevel || - (item.permissionLevel === 0) - ? - <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item> - : - null))} - - <Menu.Menu position='right'> - <Menu.Item className='item'> - { - user.id ? - <Button.Group> - <Button primary as={Link} to='/profile'>Profilom</Button> - <Button as='a' href='/api/v1/logout/'icon='sign out' /> - </Button.Group> - : - <Button as='a' href='/api/v1/login/authsch/' >Bejelentkezés</Button> - } - </Menu.Item> - </Menu.Menu> - </Container> - </Menu> -); - -class Header extends Component { - constructor(props) { - super(props); - this.state = { - visible: false, - }; - } - componentWillMount() { - this.props.getUserData(); - } - - hideFixedMenu() { - this.setState({ visible: false }); - } - - showFixedMenu() { - this.setState({ visible: true }); - } - - - render() { - const { visible } = this.state; - - return ( - <div> - {visible ? <FixedMenu user={this.props.user} /> : null} - <Visibility - onBottomPassed={() => this.showFixedMenu()} - onBottomVisible={() => this.hideFixedMenu()} - once={false} - > - <Segment inverted textAlign='center' vertical> - <Container> - <Menu inverted secondary size='large'> - - {menuItems.map((item, i) => - (this.props.user.permission >= item.permissionLevel || - (item.permissionLevel === 0) ? - <Menu.Item key={i} as={Link} to={item.to}>{item.prefix}{item.text}</Menu.Item> - : - null))} - - <Menu.Item position='right'> - { - this.props.user.id ? - <Button.Group> - <Button inverted as={Link} to='/profile'>Profilom</Button> - <Button as='a' href='/api/v1/logout/' icon='sign out' /> - </Button.Group> - : - <Button as='a' href='/api/v1/login/authsch/' inverted>Bejelentkezés</Button> - } - </Menu.Item> - - </Menu> - </Container> - </Segment> - </Visibility> - </div> - ); - } -} +const Header = ({ children, user, getUserData }) => ( + <div> + <DesktopContainer user={user} getUserData={getUserData} menuItems={menuItems}>{children}</DesktopContainer> + <MobileContainer user={user} getUserData={getUserData} menuItems={menuItems}>{children}</MobileContainer> + </div> +) const mapStateToProps = ({ user }) => ({ user, diff --git a/src/components/Main.js b/src/components/Main.js index c9e2b88152578a1ce7022ef87613e96c45049505..8f9509ef0c140e484afe954ea2f6bbd27c288a02 100644 --- a/src/components/Main.js +++ b/src/components/Main.js @@ -1,5 +1,6 @@ import React from 'react'; import { Switch, Route, Redirect, withRouter } from 'react-router-dom'; +import { Sidebar } from 'semantic-ui-react'; import Home from './pages/Home'; import Trainers from './pages/Trainers'; @@ -15,21 +16,23 @@ import EventDetail from './pages/EventDetail'; import ApplicantProfile from './pages/ApplicantProfile'; const Main = () => ( - <Switch> - <Redirect exact from='/' to='/home' /> - <Route exact path='/home' component={Home} /> - <Route path='/news' component={News} /> - <Route path='/trainers' component={Trainers} /> - <Route path='/schedule' component={Schedule} /> - <Route path='/profile' component={withRouter(Profile)} /> - <Route path='/statistics' component={Statistics} /> - <Route path='/groups' component={Groups} /> - <Route path='/homework' component={Homework} /> - <Route path='/events/:id' component={EventDetail} /> - <Route path='/applications' component={Applications} /> - <Route path='/applicant/:id' component={ApplicantProfile} /> - <Route component={NotFound} /> - </Switch> + <Sidebar.Pusher> + <Switch> + <Redirect exact from='/' to='/home' /> + <Route exact path='/home' component={Home} /> + <Route path='/news' component={News} /> + <Route path='/trainers' component={Trainers} /> + <Route path='/schedule' component={Schedule} /> + <Route path='/profile' component={withRouter(Profile)} /> + <Route path='/statistics' component={Statistics} /> + <Route path='/groups' component={Groups} /> + <Route path='/homework' component={Homework} /> + <Route path='/events/:id' component={EventDetail} /> + <Route path='/applications' component={Applications} /> + <Route path='/applicant/:id' component={ApplicantProfile} /> + <Route component={NotFound} /> + </Switch> + </Sidebar.Pusher> ); export default Main; diff --git a/src/components/forms/SolutionDetailsForm.js b/src/components/forms/SolutionDetailsForm.js index ea478511ae50ddc7527bdc1b6a6941cff26f2178..005cd935949086902f6c3f252868a47f2e4cb8bc 100644 --- a/src/components/forms/SolutionDetailsForm.js +++ b/src/components/forms/SolutionDetailsForm.js @@ -4,6 +4,9 @@ import { connect } from 'react-redux'; import CorrectSolutionForm from './CorrectSolutionForm'; import { emptyMessage } from '../pages/Homework'; import './Forms.css'; +import { + getSolutions, +} from '../../actions/homework'; class SolutionDetailsForm extends Component { constructor(props) { @@ -22,22 +25,22 @@ class SolutionDetailsForm extends Component { const noAcceptStudents = []; const acceptedStudents = []; - for (let i = 0; i < this.props.homeworks.profiles.length; i += 1) { - const profileSolutions = taskSolutions.filter(solution => - solution.created_by === this.props.homeworks.profiles[i].id); + this.props.homeworks.profiles.forEach((profile) => { + const profileSolutions = taskSolutions.filter(solution => + solution.created_by === profile.id); - if (this.props.homeworks.profiles[i].role === 'Student') { - if (profileSolutions.length === 0) { - noSubmitStudents.push(this.props.homeworks.profiles[i]); - } else if (taskSolutions[taskSolutions.length - 1].corrected === false) { - waitForCorrectionStudents.push(this.props.homeworks.profiles[i]); - } else if (taskSolutions[taskSolutions.length - 1].accepted === false) { - noAcceptStudents.push(this.props.homeworks.profiles[i]); - } else { - acceptedStudents.push(this.props.homeworks.profiles[i]); - } - } - } + if (profile.role === 'Student') { + if (profileSolutions.length === 0) { + noSubmitStudents.push(profile); + } else if (profileSolutions[profileSolutions.length - 1].corrected === false) { + waitForCorrectionStudents.push(profile); + } else if (profileSolutions[profileSolutions.length - 1].accepted === false) { + noAcceptStudents.push(profile); + } else { + acceptedStudents.push(profile); + } + } + }); const emptyStudentText = 'Nincs ilyen képzÅ‘dÅ‘ jelenleg.'; @@ -45,7 +48,13 @@ class SolutionDetailsForm extends Component { <Modal open={this.state.showModal} trigger={ - <button id='task' onClick={() => { this.setState({ showModal: true }); }}> + <button + id='task' + onClick={() => { + this.setState({ showModal: true }); + this.props.getSolutions(); + }} + > <Icon name='external' /> {this.props.tasktitle} </button> @@ -115,4 +124,5 @@ class SolutionDetailsForm extends Component { const mapStateToProps = ({ homeworks, user }) => ({ homeworks, user }); export default connect(mapStateToProps, { + getSolutions, })(SolutionDetailsForm); diff --git a/src/components/menus/DesktopContainer.js b/src/components/menus/DesktopContainer.js new file mode 100644 index 0000000000000000000000000000000000000000..214d60d916b95f540e403b1eee23be222cec003d --- /dev/null +++ b/src/components/menus/DesktopContainer.js @@ -0,0 +1,103 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { + Menu, + Container, + Button, + Segment, + Visibility, + Responsive, +} from 'semantic-ui-react'; + +const FixedMenu = ({ user, menuItems }) => ( + <Menu fixed='top' size='large' pointing> + <Container> + {menuItems.map((item, i) => + (user.permission >= item.permissionLevel || + (item.permissionLevel === 0) + ? + <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item> + : + null))} + + <Menu.Menu position='right'> + <Menu.Item className='item'> + { + user.id ? + <Button.Group> + <Button primary as={Link} to='/profile'>Profilom</Button> + <Button as='a' href='/api/v1/logout/'icon='sign out' /> + </Button.Group> + : + <Button as='a' href='/api/v1/login/authsch/' >Bejelentkezés</Button> + } + </Menu.Item> + </Menu.Menu> + </Container> + </Menu> +); + +class DesktopContainer extends Component { + constructor(props) { + super(props); + this.state = { + visible: false, + }; + } + componentWillMount() { + this.props.getUserData(); + } + + hideFixedMenu() { + this.setState({ visible: false }); + } + + showFixedMenu() { + this.setState({ visible: true }); + } + + render() { + const { visible } = this.state; + const { children, user, menuItems } = this.props; + return ( + <Responsive minWidth={768}> + {visible ? <FixedMenu user={this.props.user} menuItems={menuItems} /> : null} + <Visibility + onBottomPassed={() => this.showFixedMenu()} + onBottomVisible={() => this.hideFixedMenu()} + once={false} + > + <Segment inverted textAlign='center' vertical> + <Container> + <Menu inverted secondary stackable size='large'> + + {menuItems.map((item, i) => + (this.props.user.permission >= item.permissionLevel || + (item.permissionLevel === 0) ? + <Menu.Item key={i} as={Link} to={item.to}>{item.prefix}{item.text}</Menu.Item> + : + null))} + + <Menu.Item position='right'> + { + this.props.user.id ? + <Button.Group> + <Button inverted as={Link} to='/profile'>Profilom</Button> + <Button as='a' href='/api/v1/logout/' icon='sign out' /> + </Button.Group> + : + <Button as='a' href='/api/v1/login/authsch/' inverted>Bejelentkezés</Button> + } + </Menu.Item> + + </Menu> + </Container> + </Segment> + </Visibility> + {children} + </Responsive> + ); + } +} + +export default DesktopContainer; diff --git a/src/components/menus/MobileContainer.js b/src/components/menus/MobileContainer.js new file mode 100644 index 0000000000000000000000000000000000000000..793b52bf122defa7d27254fc62c70312bf817202 --- /dev/null +++ b/src/components/menus/MobileContainer.js @@ -0,0 +1,82 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { + Menu, + Container, + Button, + Segment, + Image, + Responsive, + Sidebar, + Icon, +} from 'semantic-ui-react'; +import KSZKlogo from '../images/kszk_logo.svg'; + + +class MobileContainer extends Component { + constructor(props) { + super(props); + this.state = { + sidebarVisible: false, + }; + } + componentWillMount() { + this.props.getUserData(); + } + + render() { + const visible = this.state.sidebarVisible; + const { children, user, menuItems } = this.props; + return( + <Responsive maxWidth={767}> + <Segment inverted textAlign='center' vertical> + <Container> + <Menu inverted secondary> + <Menu.Item onClick={visible ? this.handleHideClick : this.handleShowClick}> + <Icon name='sidebar'/> + <Image size='mini' src={KSZKlogo} style={{ marginRight: '1.5em' }} /> + </Menu.Item> + <Menu.Item position='right'> + { + this.props.user.id ? + <Button.Group> + <Button inverted as={Link} to='/profile'>Profilom</Button> + <Button as='a' href='/api/v1/logout/' icon='sign out' /> + </Button.Group> + : + <Button as='a' href='/api/v1/login/authsch/' inverted>Bejelentkezés</Button> + } + </Menu.Item> + </Menu> + </Container> + </Segment> + <Sidebar.Pushable> + <Sidebar + as={Menu} + animation='overlay' + icon='labeled' + inverted + vertical + visible={visible} + width='thin' + > + {menuItems.map((item, i) => + (this.props.user.permission >= item.permissionLevel || + (item.permissionLevel === 0) ? + <Menu.Item key={i} as={Link} to={item.to} onClick={this.handleSidebarHide}>{item.text}</Menu.Item> + : + null))} + </Sidebar> + <Sidebar.Pusher onClick={this.handleSidebarHide}> + {children} + </Sidebar.Pusher> + </Sidebar.Pushable> + </Responsive>); + } + + handleShowClick = () => this.setState({ sidebarVisible: true }) + handleHideClick = () => this.setState({ sidebarVisible: false }) + handleSidebarHide = () => this.setState({ sidebarVisible: false }) +} + +export default MobileContainer; diff --git a/src/components/pages/ApplicantProfile.js b/src/components/pages/ApplicantProfile.js index a8595aa590f64c9fc5b288138d4ddc681f7dec4c..3db7dc4c09b5c12005d88f119c2ba40f133af8ed 100644 --- a/src/components/pages/ApplicantProfile.js +++ b/src/components/pages/ApplicantProfile.js @@ -1,9 +1,21 @@ import React, { Component } from 'react'; -import { Container, Header, Item, Button, Label, List } from 'semantic-ui-react'; +import { + Container, + Header, + Item, + Button, + Label, + List, + Form, + Comment, +} from 'semantic-ui-react'; import { connect } from 'react-redux'; import { getSelectedProfile, setStatus } from '../../actions/statistics'; +import { getNotesByProfile, writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes'; import ConfirmModal from '../forms/ConfirmModal'; +import moment from 'moment'; + const options = [ { key: 'DT', text: 'DevTeam' }, { key: 'NET', text: 'NETeam' }, @@ -15,6 +27,7 @@ const options = [ class ApplicantProfile extends Component { componentWillMount() { this.props.getSelectedProfile(this.props.match.params.id); + this.props.getNotesByProfile(this.props.match.params.id); } renderGroups() { @@ -29,7 +42,45 @@ class ApplicantProfile extends Component { )); } + renderComments() { + const notes = this.props.profileNotes; + return notes.map((note) => { + if (!note.event) { + return ( + <Comment> + <Comment.Content> + <Comment.Author>{note.created_by_name}</Comment.Author> + <Comment.Metadata> + {moment(note.created_at).format('LL')} + </Comment.Metadata> + <Comment.Text> + {note.note} + </Comment.Text> + </Comment.Content> + { this.props.user.fullName === note.created_by_name ? + <ConfirmModal + text='törölni akarod a megjegyzést' + button={ + <Button + compact + color='red' + size='mini' + > + Delete + </Button> + } + onAccept={() => this.props.deleteNote(note)} + /> + : + null } + </Comment>); + } + return ''; + }); + } + render() { + const note = this.props.actualNote; const { id, signed, groups, role, full_name, nick, motivation_about, motivation_exercise, motivation_profession } = this.props.selectedProfile; return ( @@ -90,25 +141,51 @@ class ApplicantProfile extends Component { </Item.Content> </Item> { signed && role !== 'Staff' ? - <Container textAlign='center'> - <ConfirmModal - button={ - <Button - color='green' - >Jelentkezés elfogadása - </Button>} - text='elfogadod a jelentkezést' - onAccept={() => this.props.setStatus(id, 'Student')} - /> - <ConfirmModal - button={ + <Container> + <Container textAlign='center'> + <ConfirmModal + button={ + <Button + color='green' + >Jelentkezés elfogadása + </Button>} + text='elfogadod a jelentkezést' + onAccept={() => this.props.setStatus(id, 'Student')} + /> + <ConfirmModal + button={ + <Button + color='red' + >Jelentkezés elutasÃtása + </Button>} + text='elutasÃtod a jelentkezést' + onAccept={() => this.props.setStatus(id, 'Denied')} + /> + </Container> + <Comment.Group> + <Header dividing> + Megjegyzések + </Header> + {this.renderComments()} + <Form reply> + <Form.TextArea + value={note.note} + onChange={e => this.props.writeNote(e)} + /> <Button - color='red' - >Jelentkezés elutasÃtása - </Button>} - text='elutasÃtod a jelentkezést' - onAccept={() => this.props.setStatus(id, 'Denied')} - /> + onClick={() => { + this.props.postNote({ userid: id, + note: note.note }); + this.props.clearWrite(); + } + } + content='Megjegyzés hozzáadása' + labelPosition='left' + icon='edit' + primary + /> + </Form> + </Comment.Group> </Container> : null @@ -118,6 +195,18 @@ class ApplicantProfile extends Component { } } -const mapStateToProps = ({ trainees: { selectedProfile } }) => ({ selectedProfile }); +const mapStateToProps = ({ + user, + trainees: { selectedProfile }, + notes: { profileNotes, actualNote } +}) => ({ user, selectedProfile, profileNotes, actualNote }); -export default connect(mapStateToProps, { getSelectedProfile, setStatus })(ApplicantProfile); +export default connect(mapStateToProps, { + getSelectedProfile, + setStatus, + postNote, + getNotesByProfile, + writeNote, + deleteNote, + clearWrite, +})(ApplicantProfile); diff --git a/src/components/pages/EventDetail.js b/src/components/pages/EventDetail.js index 3584835e846d6a5467b121c48f4a5962b15d9499..3bb8a36264848f9d6bce65daf86ca7a6511c1dc0 100644 --- a/src/components/pages/EventDetail.js +++ b/src/components/pages/EventDetail.js @@ -11,7 +11,7 @@ import { import { connect } from 'react-redux'; import moment from 'moment'; import { getEventById, getTrainees, visitorChange, submitVisitors } from '../../actions/statistics'; -import { getNotesByEvent, writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes'; +import { getNotesByEvent, writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes'; import TraineeTableRow from './TraineeTableRow'; import ConfirmModal from '../forms/ConfirmModal'; @@ -74,19 +74,22 @@ class EventDetail extends Component { {note.note} </Comment.Text> </Comment.Content> - <ConfirmModal - text='törölni akarod a megjegyzést' - button={ - <Button - compact - color='red' - size='mini' - > - Delete - </Button> - } - onAccept={() => this.props.deleteNote(note)} - /> + { this.props.user.fullName === note.created_by_name ? + <ConfirmModal + text='törölni akarod a megjegyzést' + button={ + <Button + compact + color='red' + size='mini' + > + Delete + </Button> + } + onAccept={() => this.props.deleteNote(note)} + /> + : + null } </Comment>); } return ''; @@ -162,7 +165,7 @@ class EventDetail extends Component { /> <Button onClick={() => { - this.props.postEventNote({ eventid: event.id, + this.props.postNote({ eventid: event.id, note: note.note }); this.props.clearWrite(); } @@ -180,10 +183,11 @@ class EventDetail extends Component { } const mapStateToProps = ({ + user, notes: { eventNotes, actualNote }, events: { selectedEvent }, trainees: { trainees } -}) => ({ eventNotes, selectedEvent, trainees, actualNote }); +}) => ({ user, eventNotes, selectedEvent, trainees, actualNote }); export default connect(mapStateToProps, { getEventById, @@ -193,6 +197,6 @@ export default connect(mapStateToProps, { submitVisitors, writeNote, clearWrite, - postEventNote, + postNote, deleteNote, })(EventDetail); diff --git a/src/components/pages/Home.css b/src/components/pages/Home.css index 727ae7b87d942d04b884fd3916d4cb361bb7bedf..62080012d0c7d66ad325213eb6154807f791cba3 100644 --- a/src/components/pages/Home.css +++ b/src/components/pages/Home.css @@ -8,5 +8,6 @@ top: 0px; -webkit-text-fill-color: white; -webkit-text-stroke-color: black; - -webkit-text-stroke-width: 0.75px; + /*-webkit-text-stroke-width: 0.1vw;*/ + text-shadow: 2px 2px 2px black; } diff --git a/src/components/pages/Home.js b/src/components/pages/Home.js index ed0b4d2e36d87084942db290e6da397756e88ab1..60a764ec9ea1a11d96d53e83f927e46f9299e4d3 100644 --- a/src/components/pages/Home.js +++ b/src/components/pages/Home.js @@ -58,7 +58,7 @@ class Home extends Component { content='Ãœdvözlünk a' inverted style={{ - fontSize: '3vw', + fontSize: '2vw', fontWeight: 'normal', marginBottom: 0, marginTop: '0.5vw', @@ -69,7 +69,7 @@ class Home extends Component { content='Kollégiumi SzámÃtástechnikai Kör' inverted style={{ - fontSize: '4vw', + fontSize: '3vw', fontWeight: 'bold', marginBottom: '0.5vw', marginTop: '0.5vw', @@ -80,7 +80,7 @@ class Home extends Component { content='újoncképzésének weboldalán!' inverted style={{ - fontSize: '3vw', + fontSize: '2vw', fontWeight: 'normal', marginBottom: 0, marginTop: '0.5vw', @@ -89,52 +89,19 @@ class Home extends Component { <Image verticalAlign='middle' src={KSZKbiglogo} - style={{ marginTop: '4vw', width: '15%' }} + style={{ marginTop: '2vw', width: '12%' }} /> <Header as='h1' content='Szeretettel várunk a KSZKépzésre!' inverted style={{ - fontSize: '3vw', + fontSize: '2vw', fontWeight: 'normal', marginBottom: 0, marginTop: '1vw', }} /> - <Container> - { - this.props.user.id ? - <Button - as={Link} - to='/profile' - primary - size='huge' - style={{ - fontSize: '2vw', - marginTop: '1vw', - marginBottom: '1vw', - }} - > - Jelentkezés - <Icon name='right arrow' /> - </Button> - : - <Button - href='/api/v1/login/authsch/' - primary - size='huge' - style={{ - fontSize: '2vw', - marginTop: '1vw', - marginBottom: '1vw', - }} - > - Bejelentkezés - <Icon name='right arrow' /> - </Button> - } - </Container> </Segment> </div> </div> @@ -174,14 +141,7 @@ class Home extends Component { KeÌpzeÌsünk </Header> <p style={{ fontSize: '1.33em', fontFamily: 'Arial' }}> - Kilenc alkalmas képzésünk végén Te is igazi KSZK-ssá válhatsz, - hiszen rengeteg szakmai tudást igyekszünk átadni nektek. A - képzésalkalmak rendkÃvül jó hangulatban telnek, és a szociális - irányultságú foglalkozások alatt egy nagyon jó csapat kovácsolódik - az érdeklÅ‘dÅ‘kbÅ‘l. Az elsÅ‘ képzés idÅ‘pontja február 19. hétfÅ‘ - 20:00, ettÅ‘l kezdve pedig minden héten találkozunk ugyanabban az - idÅ‘pontban. A képzés ideje alatt április 6-8 között rendezünk - tábort. Az alkalmakon és a táboron kötelezÅ‘ a részvétel. + Kilenc alkalmas képzésünk végén Te is igazi KSZK-ssá válhatsz, hiszen rengeteg szakmai tudást igyekszünk átadni nektek. A képzésalkalmak rendkÃvül jó hangulatban telnek, és a szociális irányultságú foglalkozások alatt egy nagyon jó csapat kovácsolódik az érdeklÅ‘dÅ‘kbÅ‘l. Az elsÅ‘ képzés idÅ‘pontja február 17. vasárnap 18:50, ettÅ‘l kezdve pedig minden héten találkozunk ugyanabban az idÅ‘pontban. A képzés ideje alatt egy teljes hétvégés tábort is rendezünk majd (ennek idÅ‘pontját az Újoncdélutánig tisztázzuk). Az alkalmakon és a táboron kötelezÅ‘ a részvétel. </p> <Divider as='h4' className='header' style={{ margin: '3em 0em' }} /> <Segment inverted color='red' tertiary> diff --git a/src/components/pages/Homework.js b/src/components/pages/Homework.js index 12f8fac4e7d4110d425cc360fd301691f168a555..84b954bda94624cfe9fcd04d7c7336bb1cea7245 100644 --- a/src/components/pages/Homework.js +++ b/src/components/pages/Homework.js @@ -68,8 +68,8 @@ export const emptyMessage = (header, text, marginBottom, warning) => ( class Homework extends Component { componentDidMount() { this.props.getTasks(); - this.props.getSolutions(this.props.user.id); this.props.getProfiles(); + this.props.getSolutions(this.props.user.id); this.props.getDocuments(); } @@ -161,7 +161,11 @@ class Homework extends Component { } > <Table.Cell> - <SolutionDetailsForm taskid={task.id} tasktitle={task.title} taskdesc={task.text} /> + <SolutionDetailsForm + taskid={task.id} + tasktitle={task.title} + taskdesc={task.text} + /> </Table.Cell> <Table.Cell> {moment(task.deadline).format('YYYY. MM. DD. HH:mm')} diff --git a/src/components/pages/Profile.js b/src/components/pages/Profile.js index 9cd0d06c8c157b3d1812bda469c0275b0023cdb8..887bd13a4c5d8d7c4cd37be7dd95102c44d6036e 100644 --- a/src/components/pages/Profile.js +++ b/src/components/pages/Profile.js @@ -30,7 +30,7 @@ class Profile extends Component { > <Segment inverted color='red' tertiary> <p style={{ fontSize: '1.33em' }}> - A profilod mentés után is módosÃtható a késÅ‘bbiekben, egészen február 14. 23:59-ig. + A profilod mentés után is módosÃtható a késÅ‘bbiekben, egészen február 13. 17:00-ig. </p> </Segment> <Form> diff --git a/src/components/pages/TraineeTableRow.js b/src/components/pages/TraineeTableRow.js index 215ef8eff16bb6f818377810aa5cb923f9ad15fc..18a5b0e0549306d4044816ac72450880d8daf0a9 100644 --- a/src/components/pages/TraineeTableRow.js +++ b/src/components/pages/TraineeTableRow.js @@ -10,7 +10,7 @@ import { } from 'semantic-ui-react'; import { connect } from 'react-redux'; import { visitorChange } from '../../actions/statistics'; -import { writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes'; +import { writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes'; import CommentModal from './CommentModal' class TraineeTableRow extends Component { @@ -109,7 +109,7 @@ class TraineeTableRow extends Component { /> <Button onClick={() => { - this.props.postEventNote({ eventid:selectedEvent.id, + this.props.postNote({ eventid:selectedEvent.id, userid: trainee.id, note: this.state.note }); this.clearWrite(); @@ -132,4 +132,4 @@ class TraineeTableRow extends Component { } } -export default connect(() => ({}), { writeNote, clearWrite, postEventNote, visitorChange, deleteNote })(TraineeTableRow) +export default connect(() => ({}), { writeNote, clearWrite, postNote, visitorChange, deleteNote })(TraineeTableRow) diff --git a/src/index.js b/src/index.js index 2ccbb98c63d99aad688518269a25da632ca3a9c0..cf5d3e0ccfd2970e1683f92d856038cebb2d5725 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,6 @@ import moment from 'moment'; import configureStore from './configureStore'; import App from './components/App'; -import registerServiceWorker from './registerServiceWorker'; moment.locale(); @@ -27,5 +26,3 @@ render( </Provider>, document.getElementById('root'), ); - -registerServiceWorker(); diff --git a/src/reducers/MessageReducer.js b/src/reducers/MessageReducer.js new file mode 100644 index 0000000000000000000000000000000000000000..e0016ce0c7068b0d452e2d57adc966a16e21b0a7 --- /dev/null +++ b/src/reducers/MessageReducer.js @@ -0,0 +1,14 @@ +import { SHOW_MESSAGE, DISMISS_MESSAGE } from '../actions/types'; + +const INITIAL_STATE = {}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case SHOW_MESSAGE: + return { text: action.text, messageType: action.messageType, visible: true }; + case DISMISS_MESSAGE: + return { text: '', type: '', visible: false }; + default: + return state; + } +}; diff --git a/src/reducers/NoteReducer.js b/src/reducers/NoteReducer.js index 37caf2f13db724e0a386e7158fab0b5ae103bded..68730407755e7d8c3a5fce54edb37a7a7f0c563e 100644 --- a/src/reducers/NoteReducer.js +++ b/src/reducers/NoteReducer.js @@ -4,23 +4,30 @@ import { ADD_EVENT_NOTE, CLEAR_WRITE, DELETE_NOTE, + GET_NOTES_BY_PROFILE, + ADD_PROFILE_NOTE, } from '../actions/types'; -const INITIAL_STATE = { eventNotes: [], actualNote: {} }; +const INITIAL_STATE = { eventNotes: [], actualNote: {}, profileNotes: [] }; export default (state = INITIAL_STATE, action) => { switch (action.type) { case GET_NOTES_BY_EVENT: return { ...state, eventNotes: action.payload }; + case GET_NOTES_BY_PROFILE: + return { ...state, profileNotes: action.payload }; case WRITE_NOTE: return { ...state, actualNote: { ...state.actualNote, note: action.payload } }; case ADD_EVENT_NOTE: return { ...state, eventNotes: [...state.eventNotes, action.payload] }; + case ADD_PROFILE_NOTE: + return { ...state, profileNotes: [...state.profileNotes, action.payload] }; case CLEAR_WRITE: return { ...state, actualNote: { note: '' } }; case DELETE_NOTE: state.eventNotes.splice(state.eventNotes.indexOf(action.payload), 1); - return { ...state, eventNotes: [...state.eventNotes] }; + state.profileNotes.splice(state.profileNotes.indexOf(action.payload), 1); + return { ...state, eventNotes: [...state.eventNotes], profileNotes: [...state.profileNotes] }; default: return state; } diff --git a/src/reducers/index.js b/src/reducers/index.js index 2464c572a060e17e375effcb11717ebbc430f479..d2c02939efd57b15e8cd9f5803f5946c444d98ed 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,24 +7,26 @@ import HomeworksReducer from './HomeworksReducer'; import AddTaskReducer from './AddTaskReducer'; import AddSolutionReducer from './AddSolutionReducer'; import EventReducer from './EventReducer'; -import TraineeReducer from './TraineeReducer'; import NoteReducer from './NoteReducer'; +import TraineeReducer from './TraineeReducer'; import CorrectSolutionReducer from './CorrectSolutionReducer'; import EditTaskReducer from './EditTaskReducer'; +import MessageReducer from './MessageReducer'; const rootReducer = combineReducers({ user: UserReducer, news: NewsReducer, newNews: AddNewsReducer, selectedNews: EditNewsReducer, - homeworks: HomeworksReducer, - correction: CorrectSolutionReducer, - newTask: AddTaskReducer, selectedTask: EditTaskReducer, - newSolution: AddSolutionReducer, events: EventReducer, trainees: TraineeReducer, notes: NoteReducer, + homeworks: HomeworksReducer, + newTask: AddTaskReducer, + newSolution: AddSolutionReducer, + correction: CorrectSolutionReducer, + message: MessageReducer, }); export default rootReducer; diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js deleted file mode 100644 index 4a3ccf02124e9a3a84c0a754ec5eaf577499ae35..0000000000000000000000000000000000000000 --- a/src/registerServiceWorker.js +++ /dev/null @@ -1,108 +0,0 @@ -// In production, we register a service worker to serve assets from local cache. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on the "N+1" visit to a page, since previously -// cached resources are updated in the background. - -// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. -// This link also includes instructions on opting out of this behavior. - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -export default function register() { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (!isLocalhost) { - // Is not local host. Just register service worker - registerValidSW(swUrl); - } else { - // This is running on localhost. Lets check if a service worker still exists or not. - checkValidServiceWorker(swUrl); - } - }); - } -} - -function registerValidSW(swUrl) { - navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the old content will have been purged and - // the fresh content will have been added to the cache. - // It's the perfect time to display a "New content is - // available; please refresh." message in your web app. - console.log('New content is available; please refresh.'); - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - if ( - response.status === 404 || - response.headers.get('content-type').indexOf('javascript') === -1 - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); - } -}