Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • kszk/devteam/kszkepzes/old/kszkepzes-frontend
  • kbgergely/kszkepzes-frontend
2 results
Show changes
Showing
with 619 additions and 543 deletions
import './News.css';
import { Button, Container, Grid, Item, Segment } from 'semantic-ui-react';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Container, Segment, Item, Button, Grid } from 'semantic-ui-react'; import { deleteNews, getNews, setSelectedNews } from '../../actions/news';
import { connect } from 'react-redux';
import moment from 'moment';
import ConfirmModal from '../forms/ConfirmModal';
import AddNewsForm from '../forms/AddNewsForm'; import AddNewsForm from '../forms/AddNewsForm';
import ConfirmModal from '../forms/ConfirmModal';
import EditNewsForm from '../forms/EditNewsForm'; import EditNewsForm from '../forms/EditNewsForm';
import { connect } from 'react-redux';
import moment from 'moment';
import { getNews, deleteNews, setSelectedNews } from '../../actions/news'; const linkify = (text) => {
const urlRegex = /(https?:\/\/[^\s]+)/g;
import './News.css'; return text.split(urlRegex).map((part, index) =>
part.match(urlRegex) ? (
<a key={index} href={part} target="_blank" rel="noopener noreferrer">
{part}
</a>
) : (
part
)
);
};
class News extends Component { class News extends Component {
componentWillMount() { UNSAFE_componentWillMount() {
this.props.getNews(); this.props.getNews();
} }
renderNews() { renderNews() {
return this.props.news.map(item => ( return this.props.news.map((item) => (
<Item key={item.id}> <Item key={item.id}>
<Item.Content> <Item.Content>
<Container text textAlign='left'> <Container text textAlign="left">
<Item.Header <Item.Header style={{ fontSize: '2em', width: '100%' }}>
style={{ fontSize: '2em', width: '100%' }}
>
<Grid> <Grid>
<Grid.Column <Grid.Column
floated='left' floated="left"
width={this.props.user.role === 'Staff' ? 12 : 16} width={this.props.user.role === 'Staff' ? 12 : 16}
> >
{item.title} {item.title}
</Grid.Column> </Grid.Column>
{ this.props.user.role === 'Staff' ? {this.props.user.role === 'Staff' ? (
<Grid.Column floated='right' width={4}> <Grid.Column floated="right" width={4}>
<EditNewsForm <EditNewsForm
onClick={() => this.props.setSelectedNews(item)} onClick={() => this.props.setSelectedNews(item)}
/> />
<ConfirmModal <ConfirmModal
text={`törölni akarod a következő hírt: ${item.title}`} text={`törölni akarod a következő hírt: ${item.title}`}
button={ button={
<Button <Button compact color="red" size="mini">
compact Törlés
color='red'
size='mini'
>
Törlés
</Button> </Button>
} }
onAccept={() => this.props.deleteNews(item)} onAccept={() => this.props.deleteNews(item)}
/> />
</Grid.Column> </Grid.Column>
: null } ) : null}
</Grid> </Grid>
</Item.Header> </Item.Header>
<Item.Meta style={{ fontSize: '0.75em', fontStyle: 'italic' }}>Közzétéve: {moment(item.created_at).format('LLLL')}</Item.Meta> <Item.Meta style={{ fontSize: '0.75em', fontStyle: 'italic' }}>
<Item.Description className='news-text' style={{ fontSize: '1em' }}> Közzétéve:
{moment(item.created_at).format('LLLL')}
</Item.Meta>
<Item.Description className="news-text" style={{ fontSize: '1em' }}>
{this.renderMultiLine(item.text)} {this.renderMultiLine(item.text)}
</Item.Description> </Item.Description>
</Container> </Container>
</Item.Content> </Item.Content>
</Item> </Item>
)); ));
} }
renderMultiLine(text) { renderMultiLine = (text) => {
const strings = text.split('\n'); const strings = text.split('\n');
return strings.map(string => <p>{string}</p>); return strings.map((string) => <p key={Math.random()}>{linkify(string)}</p>);
} };
render() { render() {
return ( return (
<div> <div style={{ paddingTop: '1em', paddingBottom: '5em' }}>
<Segment style={{ padding: '3em 3em' }} vertical> <Segment vertical>
{/* { this.props.user.is_superuser ? <AddNewsForm /> : ''} */} {/* { this.props.user.is_superuser ? <AddNewsForm /> : ''} */}
<Container text textAlign='center' style={{ marginBottom: '3em' }}> <Container text textAlign="center">
{this.props.user.role === 'Staff' ? {this.props.user.role === 'Staff' ? <AddNewsForm /> : null}
<AddNewsForm /> <Item.Group divided>{this.renderNews()}</Item.Group>
:
null}
<Item.Group divided>
{this.renderNews()}
</Item.Group>
</Container> </Container>
</Segment> </Segment>
</div> </div>
...@@ -88,7 +92,10 @@ class News extends Component { ...@@ -88,7 +92,10 @@ class News extends Component {
} }
} }
const mapStateToProps = ({ news, user }) => ({ news, user }); const mapStateToProps = ({ news, user }) => ({ news, user });
export default connect(mapStateToProps, { getNews, deleteNews, setSelectedNews })(News); export default connect(mapStateToProps, {
getNews,
deleteNews,
setSelectedNews,
})(News);
import React, { Component } from 'react';
import { Button, Container, Header, Icon, Segment } from 'semantic-ui-react'; import { Button, Container, Header, Icon, Segment } from 'semantic-ui-react';
import React, { Component } from 'react';
export default class NotFound extends Component { export default class NotFound extends Component {
render() { render() {
return ( return (
<div> <div>
<Segment inverted textAlign='center' vertical> <Segment inverted textAlign="center" vertical>
<Container> <Container>
<Header <Header
as='h1' as="h1"
content='404 - A keresett oldal nem található!' content="404 - A keresett oldal nem található!"
inverted inverted
style={{ style={{
fontSize: '3em', fontSize: '3em',
...@@ -19,9 +19,9 @@ export default class NotFound extends Component { ...@@ -19,9 +19,9 @@ export default class NotFound extends Component {
}} }}
/> />
<Button <Button
href='/' href="/"
primary primary
size='huge' size="huge"
style={{ style={{
fontSize: '2em', fontSize: '2em',
marginTop: '1em', marginTop: '1em',
...@@ -29,7 +29,7 @@ export default class NotFound extends Component { ...@@ -29,7 +29,7 @@ export default class NotFound extends Component {
}} }}
> >
Vissza a Főoldalra Vissza a Főoldalra
<Icon name='right arrow' /> <Icon name="right arrow" />
</Button> </Button>
</Container> </Container>
</Segment> </Segment>
......
import { Container, Icon, Table } from 'semantic-ui-react';
import React, { Component } from 'react';
import { getStaffEvents, getTrainees } from '../../actions/statistics';
import { connect } from 'react-redux';
class Presence extends Component {
UNSAFE_componentWillMount() {
this.props.getTrainees();
this.props.getStaffEvents();
}
// Every event with visit status in table cells
renderVisitedStatus(trainee) {
return this.props.events.map((event) => {
if (event.visitors.includes(trainee.id)) {
return (
<Table.Cell textAlign="center" key={Math.random()}>
<Icon color="green" name="checkmark" />
</Table.Cell>
);
}
return (
<Table.Cell textAlign="center" key={Math.random()}>
<Icon color="red" name="cancel" />
</Table.Cell>
);
});
}
// Every event rendered
renderTraineesWithEvents() {
return this.props.trainees.map((trainee) =>
trainee.role === 'Student' ? (
<Table.Row key={Math.random()}>
<Table.Cell textAlign="center">{trainee.full_name}</Table.Cell>
{this.renderVisitedStatus(trainee)}
</Table.Row>
) : null
);
}
// Column for each event
renderTableHeaderEvents() {
return this.props.events.map((event) => (
<Table.HeaderCell textAlign="center" key={event.id}>
{event.name}
</Table.HeaderCell>
));
}
render() {
return (
<Container textAlign="center" style={{ overflowX: 'scroll' }}>
<Table color="blue" unstackable celled selectable compact>
<Table.Header>
<Table.Row>
<Table.HeaderCell textAlign="center">Képződők</Table.HeaderCell>
{this.renderTableHeaderEvents()}
</Table.Row>
</Table.Header>
<Table.Body>
{this.props.trainees ? (
this.renderTraineesWithEvents()
) : (
<Table.Row>
<Table.Cell>Nincsenek képződők</Table.Cell>
</Table.Row>
)}
</Table.Body>
</Table>
</Container>
);
}
}
const mapStateToProps = ({
trainees: { trainees },
events: { events },
user,
}) => ({ trainees, events, user });
export default connect(mapStateToProps, { getTrainees, getStaffEvents })(
Presence
);
import React, { Component } from 'react'; import { Container, Divider, Dropdown, Form, Segment } from "semantic-ui-react";
import { Container, Form, Dropdown, Divider, Segment } from 'semantic-ui-react'; import React, { Component } from "react";
import { connect } from 'react-redux'; import { groupChange, submitRegistration, textChange } from "../../actions";
import { textChange, submitRegistration, groupChange } from '../../actions';
import HiddenForm from "../forms/HiddenForm";
import { connect } from "react-redux";
import { getDeadline } from "../../actions/auth";
const options = [ const options = [
{ key: 'DT', text: 'DevTeam', value: 'DT' }, { key: "DT", text: "DevTeam", value: "DT" },
{ key: 'NET', text: 'NETeam', value: 'NET' }, { key: "NET", text: "NETeam", value: "NET" },
{ key: 'ST', text: 'SecurITeam', value: 'ST' }, { key: "ST", text: "SecurITeam", value: "ST" },
{ key: 'SYS', text: 'SysAdmin', value: 'SYS' }, { key: "SYS", text: "SysAdmin", value: "SYS" },
{ key: 'HAT', text: 'Hallgatói Tudásbázis', value: 'HAT' }, { key: "HAT", text: "Hallgatói Tudásbázis", value: "HAT" },
]; ];
class Profile extends Component { class Profile extends Component {
componentWillMount() { UNSAFE_componentWillMount() {
this.props.getDeadline();
if (!this.props.id) { if (!this.props.id) {
this.props.history.push('/home'); this.props.history.push("/home");
} }
} }
render() { render() {
const { const {
role, nick, groups, motivationAbout, motivationProfession, motivationExercise, signed, id, nick,
groups,
motivationAbout,
motivationProfession,
motivationExercise,
signed,
id,
deadline,
messageBefore,
messageAfter,
} = this.props; } = this.props;
const endDate = new Date(deadline);
const canEdit = Date.now() < endDate;
return ( return (
<Container <Container
style={{ style={{
marginTop: '0.5em', marginTop: "1em",
}} }}
> >
<Segment inverted color='red' tertiary> {canEdit ? (
<p style={{ fontSize: '1.33em' }}> <Segment inverted color="red" tertiary>
A profilod mentés után is módosítható a későbbiekben, egészen február 13. 17:00-ig. <p
</p> style={{ fontSize: "1.3em" }}
</Segment> dangerouslySetInnerHTML={{ __html: messageBefore }}
<Form> />
<Form.Input </Segment>
fluid ) : (
name='nick' <Segment inverted color="red" tertiary>
label='Becenév' <p
onChange={e => this.props.textChange(e)} style={{ fontSize: "1.3em" }}
placeholder='Becenév' dangerouslySetInnerHTML={{ __html: messageAfter }}
value={nick} />
/> </Segment>
)}
<Form>
{canEdit ? (
<Form.Input
fluid
name="nick"
label="Becenév"
onChange={(e) => this.props.textChange(e)}
placeholder="Becenév"
value={nick}
/>
) : (
<HiddenForm fontWeight="bold" label="Becenév" value={nick} />
)}
<Divider horizontal>Motiváció</Divider> <Divider horizontal>Motiváció</Divider>
<Form.TextArea {canEdit ? (
rows={10} <Form.TextArea
name='motivationAbout' rows={10}
label='Mesélj nekünk egy kicsit magadról. Milyen szakmai vagy más eredményeket értél el, amikre büszke vagy?' name="motivationAbout"
onChange={e => this.props.textChange(e)} label="Mesélj nekünk egy kicsit magadról. Milyen szakmai vagy más eredményeket értél el, amikre büszke vagy?"
placeholder='Mesélj nekünk egy kicsit magadról. Milyen szakmai vagy más eredményeket értél el, amikre büszke vagy?' onChange={(e) => this.props.textChange(e)}
value={motivationAbout} placeholder="Mesélj nekünk egy kicsit magadról. Milyen szakmai vagy más eredményeket értél el, amikre büszke vagy?"
/> value={motivationAbout}
/>
) : (
<HiddenForm
fontWeight="bold"
label="Mesélj nekünk egy kicsit magadról. Milyen szakmai vagy más eredményeket értél el, amikre büszke vagy?"
value={motivationAbout}
/>
)}
<Divider horizontal /> <Divider horizontal />
<Form.TextArea {canEdit ? (
rows={10} <Form.TextArea
label='Mit vársz el a képzéstől, miért szeretnél rá jelentkezni, szerinted mire tudod majd használni az itt megszerzett tudást? Mit szeretnél elérni a szakmádban?' rows={10}
name='motivationProfession' label="Mit vársz el a képzéstől, miért szeretnél rá jelentkezni, szerinted mire tudod majd használni az itt megszerzett tudást? Mit szeretnél elérni a szakmádban?"
onChange={e => this.props.textChange(e)} name="motivationProfession"
placeholder='Mit vársz el a képzéstől, miért szeretnél rá jelentkezni, szerinted mire tudod majd használni az itt megszerzett tudást? Mit szeretnél elérni a szakmádban?' onChange={(e) => this.props.textChange(e)}
value={motivationProfession} placeholder="Mit vársz el a képzéstől, miért szeretnél rá jelentkezni, szerinted mire tudod majd használni az itt megszerzett tudást? Mit szeretnél elérni a szakmádban?"
/> value={motivationProfession}
/>
) : (
<HiddenForm
fontWeight="bold"
label="Mit vársz el a képzéstől, miért szeretnél rá jelentkezni, szerinted mire tudod majd használni az itt megszerzett tudást? Mit szeretnél elérni a szakmádban?"
value={motivationProfession}
/>
)}
<Divider horizontal /> <Divider horizontal />
<Form.TextArea {canEdit ? (
rows={10} <Form.TextArea
name='motivationExercise' rows={10}
onChange={e => this.props.textChange(e)} name="motivationExercise"
placeholder='' onChange={(e) => this.props.textChange(e)}
label={ placeholder=""
<div> label={
<b>Alább találsz néhány elgondolkodtató kérdést, megoldandó feladatot. <div>
A kérdések és feladatok elkészítése opcionális, <b>
nem titkolt célunk ezzel a lelkesedés felmérése. Alább találsz néhány elgondolkodtató kérdést, megoldandó
A válaszokat a kérdések alatti szövegdobozba várjuk. feladatot. A kérdések és feladatok elkészítése opcionális,
</b> nem titkolt célunk ezzel a lelkesedés felmérése. A
<ol> válaszokat a kérdések alatti szövegdobozba várjuk.
<li> </b>
Szeretnéd kedvenc tantárgyad vik.wiki oldalát elérni, <ul>
de szomorúan látod, hogy az oldal nem jön be. <li>
A Steam pedig hibátlanul megy a háttérben és az emailek is megérkeznek... Szeretnéd kedvenc tantárgyad vik.wiki oldalát elérni, de
Szobatársadnak pont megvan a vik.wiki szerverének IP-címe. szomorúan látod, hogy az oldal nem jön be. A Steam pedig
Csodálkozva látod, hogy a böngésző címsorába írva eléred a kiszolgáló webszervert. hibátlanul megy a háttérben és az emailek is
Mi lehet a baj? megérkeznek... Szobatársadnak pont megvan a vik.wiki
</li> szerverének IP-címe. Csodálkozva látod, hogy a böngésző
<br /> címsorába írva eléred a kiszolgáló webszervert. Mi lehet a
<li> baj?
Két előadás közti szünetben úgy döntesz, </li>
hogy laptopoddal az index.hu tech cikkeit fogod görgetni. <br />
Ám az oldal nem válaszol, a hiba okát megpróbálod kideríteni. <li>
Ekkor veszed észre, hogy az alábbiakat sem éred el: Kicsit hosszúra nyúlt az előadás és lassan rohannod kell
sze.hu, 444.hu, corvinus.hu, startlap.hu. haza, ezért úgy döntesz, hogy megnézed a menetrendet a
Ugyanakkor a Facebook, a Gmail, a YouTube, de még az egyetemi menetrendek.hu weboldalon. Ám az oldal nem válaszol, a
oldalak többsége is működik. Szerinted mi lehet a hiba oka? hiba okát megpróbálod kideríteni. Ekkor veszed észre, hogy
</li> az alábbiakat sem éred el: sze.hu, corvinus.hu,
<br /> startlap.hu. Ugyanakkor a Facebook, a Gmail, a YouTube, de
<li> még az egyetemi oldalak többsége is működik. Szerinted mi
Találsz egy értelmetlen szöveget egy honlapon (például: <a href='http://kszkepzes18.sch.bme.hu/zebra.html'>http://kszkepzes18.sch.bme.hu/zebra.html</a>), de feltűnik, hogy két egyenlőségjellel fejeződik be. Nyomozz, s a végeredményt (amit találtál) írd ide! lehet a hiba oka?
</li> </li>
<br /> <br />
<li> <li>
A <b>kszkepzes18.sch.bme.hu</b> címen elérhető gépen Találsz egy értelmetlen szöveget egy honlapon (például:{" "}
fut egy szolgáltatás az alapértelmezett <b>5432</b> porton <a href="https://ujonc.kszk.bme.hu/kepzes-media/public/zebra.html">
(használd az előző feladatban kapott adatokat). https://ujonc.kszk.bme.hu/kepzes-media/public/zebra.html
Belépés után keresd meg a feladat megoldását! </a>
</li> ), de feltűnik, hogy egyenlőségjellel fejeződik be.
</ol> Nyomozz, s a végeredményt (amit találtál) írd ide!
</div> </li>
} <br />
value={motivationExercise} <li>
/> A <b>ujonc-gres.kszk.bme.hu</b> címen elérhető gépen fut
egy szolgáltatás az alapértelmezett <b>5432</b> porton
(használd az előző feladatban kapott adatokat). Belépés
után írd le mit találtál!
</li>
</ul>
</div>
}
value={motivationExercise}
/>
) : (
<HiddenForm
fontWeight="normal"
label={
<div>
<b>
Alább találsz néhány elgondolkodtató kérdést, megoldandó
feladatot. A kérdések és feladatok elkészítése opcionális,
nem titkolt célunk ezzel a lelkesedés felmérése. A
válaszokat a kérdések alatti szövegdobozba várjuk.
</b>
<ul>
<li>
Szeretnéd kedvenc tantárgyad vik.wiki oldalát elérni, de
szomorúan látod, hogy az oldal nem jön be. A Steam pedig
hibátlanul megy a háttérben és az emailek is
megérkeznek... Szobatársadnak pont megvan a vik.wiki
szerverének IP-címe. Csodálkozva látod, hogy a böngésző
címsorába írva eléred a kiszolgáló webszervert. Mi lehet a
baj?
</li>
<br />
<li>
Kicsit hosszúra nyúlt az előadás és lassan rohannod kell
haza, ezért úgy döntesz, hogy megnézed a menetrendet a
menetrendek.hu weboldalon. Ám az oldal nem válaszol, a
hiba okát megpróbálod kideríteni. Ekkor veszed észre, hogy
az alábbiakat sem éred el: sze.hu, corvinus.hu,
startlap.hu. Ugyanakkor a Facebook, a Gmail, a YouTube, de
még az egyetemi oldalak többsége is működik. Szerinted mi
lehet a hiba oka?
</li>
<br />
<li>
Találsz egy értelmetlen szöveget egy honlapon (például:{" "}
<a href="https://ujonc.kszk.bme.hu/kepzes-media/public/zebra.html">
https://ujonc.kszk.bme.hu/kepzes-media/public/zebra.html
</a>
), de feltűnik, hogy egyenlőségjellel fejeződik be.
Nyomozz, s a végeredményt (amit találtál) írd ide!
</li>
<br />
<li>
A <b>ujonc-gres.kszk.bme.hu</b> címen elérhető gépen fut
egy szolgáltatás az alapértelmezett <b>5432</b> porton
(használd az előző feladatban kapott adatokat). Belépés
után keresd meg a feladat megoldását!
</li>
</ul>
</div>
}
value={motivationExercise}
/>
)}
<Divider horizontal>Érdekelődés</Divider> <Divider horizontal>Érdeklődés</Divider>
<Dropdown <Dropdown
fluid fluid
multiple multiple
selection selection
placeholder='DevTeam, ...' placeholder="DevTeam, ..."
onChange={(_, v) => this.props.groupChange(v.value)} onChange={(_, v) => this.props.groupChange(v.value)}
options={options} options={options}
defaultValue={groups} defaultValue={groups}
disabled={!canEdit}
/> />
<br /> <br />
{ role === 'Applicant' ? <Form.Checkbox
<Form.Checkbox name="signed"
name='signed' label="Szeretnék a képzés során emaileket kapni és jelentkezni a KSZKépzésre"
label='Szeretnék jelentkezni a KSZKépzésre' onChange={(_, v) =>
onChange={(_, v) => this.props.textChange({
this.props.textChange({ target: { name: v.name, value: v.checked } }) target: { name: v.name, value: v.checked },
})
}
checked={signed}
readOnly={!canEdit}
style={!canEdit ? { marginBottom: "5em" } : null}
/>
{canEdit ? (
<Form.Button
primary
style={{ marginBottom: "5em" }}
disabled={!signed}
onClick={() =>
this.props.submitRegistration({
nick,
motivationAbout,
motivationProfession,
motivationExercise,
signed,
groups,
id,
})
} }
checked={signed} >
/> Mentés
: </Form.Button>
null ) : (
} ""
<Form.Button )}
primary
style={{ marginBottom: '10em' }}
onClick={() => this.props.submitRegistration({
nick, motivationAbout, motivationProfession, motivationExercise, signed, groups, id,
})}
>
Mentés
</Form.Button>
</Form> </Form>
</Container> </Container>
); );
...@@ -152,10 +273,18 @@ class Profile extends Component { ...@@ -152,10 +273,18 @@ class Profile extends Component {
const mapStateToProps = ({ const mapStateToProps = ({
user: { user: {
role, nick, groups, motivationAbout, motivationProfession, motivationExercise, signed, id, nick,
groups,
motivationAbout,
motivationProfession,
motivationExercise,
signed,
id,
deadline,
messageBefore,
messageAfter,
}, },
}) => ({ }) => ({
role,
nick, nick,
groups, groups,
motivationAbout, motivationAbout,
...@@ -163,6 +292,14 @@ const mapStateToProps = ({ ...@@ -163,6 +292,14 @@ const mapStateToProps = ({
motivationExercise, motivationExercise,
signed, signed,
id, id,
deadline,
messageBefore,
messageAfter,
}); });
export default connect(mapStateToProps, { textChange, submitRegistration, groupChange })(Profile); export default connect(mapStateToProps, {
textChange,
submitRegistration,
groupChange,
getDeadline,
})(Profile);
import React, { Component } from 'react'; import "moment/locale/hu";
import { Container, Accordion, Icon, Grid } from 'semantic-ui-react';
import { connect } from 'react-redux'; import {
import moment from 'moment'; Accordion,
import { getStudentEvents } from '../../actions/statistics'; Container,
Grid,
Header,
Icon,
Segment,
} from "semantic-ui-react";
import React, { Component } from "react";
import { connect } from "react-redux";
import { getStudentEvents } from "../../actions/statistics";
import moment from "moment";
class Schedule extends Component { class Schedule extends Component {
state = { activeIndex: 0 } // eslint-disable-next-line react/state-in-constructor
state = { activeIndex: 0 };
componentWillMount() { UNSAFE_componentWillMount() {
this.props.getStudentEvents(); this.props.getStudentEvents();
} }
handleClick = (e, titleProps) => { handleClick = (e, titleProps) => {
const { index } = titleProps const { index } = titleProps;
const { activeIndex } = this.state const { activeIndex } = this.state;
const newIndex = activeIndex === index ? -1 : index const newIndex = activeIndex === index ? -1 : index;
this.setState({ activeIndex: newIndex }) this.setState({ activeIndex: newIndex });
} };
render() { render() {
const { activeIndex } = this.state const { activeIndex } = this.state;
const events = this.props.events; const { events } = this.props;
const panels = events.map(event => ( const panels = events
<div> .sort((a, b) => a.date - b.date)
<Accordion.Title .map((event) => (
active={activeIndex === event.id} <Accordion key={Math.random()}>
index={event.id} <Accordion.Title
onClick={this.handleClick} active={activeIndex === event.id}
> index={event.id}
<h3> onClick={this.handleClick}
<Grid> >
<Grid.Column floated='left' width={8} textAlign='left'> <h2>
<Icon name='angle right' color='blue' />{event.name} <Grid>
</Grid.Column> <Grid.Column floated="left" width={5} textAlign="left">
<Grid.Column floated='right' width={8} textAlign='right'> <Icon name="calendar alternate outline" color="blue" />{" "}
{moment(event.date).locale('hu').format('LLLL')} {event.name}
</Grid.Column> </Grid.Column>
</Grid> <Grid.Column floated="right" width={8} textAlign="right">
</h3> {moment(event.date).locale("hu").format("LLLL")}
</Accordion.Title> </Grid.Column>
<Accordion.Content active={activeIndex === event.id}> </Grid>
<h4>Leírás:</h4> </h2>
<p> </Accordion.Title>
{event.description} <Accordion.Content active={activeIndex === event.id}>
</p> <Segment textAlign="left" style={{ overflowWrap: "break-word" }}>
</Accordion.Content> {event.description}
</div> </Segment>
)); </Accordion.Content>
</Accordion>
));
return ( return (
<Container <div>
textAlign='left' <Container textAlign="center">
style={{ <Header
padding: '60px' as="h1"
}} content="Képzés alkalmak"
> style={{
<h2>Képzésalkalmak:</h2> fontSize: "2em",
<Accordion fontWeight: "bold",
fluid marginBottom: "0.5em",
styled marginTop: "0.5em",
defaultActiveIndex={-1} }}
panels={panels} />
> <Accordion fluid styled>
{panels} {panels}
</Accordion> </Accordion>
</Container> <Header
as="h1"
content="Tábor: április 11-13"
style={{
fontSize: "2em",
fontWeight: "bold",
marginBottom: "0.5em",
marginTop: "1.5em",
}}
/>
</Container>
</div>
); );
} }
} }
const mapStateToProps = ({ events: { events }, user }) => ({ events, user }); const mapStateToProps = ({ events: { events }, user }) => ({ events, user });
export default connect(mapStateToProps, { getStudentEvents })(Schedule); export default connect(mapStateToProps, { getStudentEvents })(Schedule);
import React, { Component } from 'react';
import { Container, Menu } from 'semantic-ui-react'; import { Container, Menu } from 'semantic-ui-react';
import Events from './Events' import React, { Component } from 'react';
import Trainees from './Trainees'
import Events from './Events';
import LeaderBoard from './LeaderBoard';
import Presence from './Presence';
export default class Statistics extends Component { export default class Statistics extends Component {
state = { activeItem: 'events' } // eslint-disable-next-line react/state-in-constructor
handleItemClick = (e, { name }) => this.setState({ activeItem: name }) state = { activeItem: 'events' };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() { render() {
const { activeItem } = this.state const { activeItem } = this.state;
return ( return (
<div> <div>
<Container <Container
textAlign="center" textAlign="center"
style={{ style={{ paddingBottom: '5em', paddingTop: '1em' }}
padding: '60px', >
}} <Menu tabular attached="top" size="huge" compact>
>
<Menu
attached='top'
tabular
size='huge'
compact={true}>
<Menu.Item <Menu.Item
name='events' name="events"
active={activeItem === 'events'} active={activeItem === 'events'}
onClick={this.handleItemClick} onClick={this.handleItemClick}
>Alkalmak >
Alkalmak
</Menu.Item>
<Menu.Item
name="presence"
active={activeItem === 'presence'}
onClick={this.handleItemClick}
>
Jelenlét
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
name='trainees' name="leaderboard"
active={activeItem === 'trainees'} active={activeItem === 'leaderboard'}
onClick={this.handleItemClick} onClick={this.handleItemClick}
>Képződők >
Ranglista
</Menu.Item> </Menu.Item>
</Menu> </Menu>
{ activeItem === 'events' ? <Events /> : '' } {activeItem === 'events' ? <Events /> : ''}
{ activeItem === 'trainees' ? <Trainees /> : '' } {activeItem === 'presence' ? <Presence /> : ''}
{activeItem === 'leaderboard' ? <LeaderBoard /> : ''}
</Container> </Container>
</div> </div>
); );
......
import React, { Component } from 'react';
import {
Comment,
Table,
Icon,
Popup,
Grid,
Button,
Form,
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { visitorChange } from '../../actions/statistics';
import { writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes';
import CommentModal from './CommentModal'
class TraineeTableRow extends Component {
constructor(props) {
super(props);
this.state = {
note: '',
}
}
handleWrite = (e) => {
this.setState({ ...this.state, note: e.target.value });
}
clearWrite = () => {
this.setState({ ...this.state, note: '' });
}
render() {
const { trainee, edit, selectedEvent, notes } = this.props;
const isVisitor = selectedEvent.visitors.includes(trainee.id);
const isAbsent = selectedEvent.absent.includes(trainee.id);
return (
<Table.Row key={trainee.id}>
<Table.Cell>
{trainee.full_name}
</Table.Cell>
{!edit ?
<Table.Cell textAlign='center'>
{
isVisitor ?
<Icon color='green' name='checkmark' />
:
isAbsent ?
<Icon color='orange' name='minus' />
:
<Icon color='red' name='cancel' />
}
</Table.Cell>
:
<Table.Cell textAlign='center'>
<Button
compact
icon={<Icon color='green' name='checkmark' />}
color={isVisitor ? 'blue' : 'lightgrey'}
onClick={() => this.props.visitorChange({ id: trainee.id, value: 'Visitor' })}
/>
<Button
compact
icon={<Icon color='orange' name='minus' />}
color={isAbsent ? 'blue' : 'lightgrey'}
onClick={() => this.props.visitorChange({ id: trainee.id, value: 'Absent' })}
/>
<Button
compact
icon={<Icon color='red' name='cancel' />}
color={!isVisitor && !isAbsent ? 'blue' : 'lightgrey'}
onClick={() => this.props.visitorChange({ id: trainee.id, value: 'No' })}
/>
</Table.Cell>
}
<Table.Cell>
<Grid>
<Grid.Row>
<Grid.Column floated='left' width={11} textAlign='left'>
{notes.length > 0 ?
<Comment>
<Comment.Content>
<Comment.Author>{notes[0].created_by_name}</Comment.Author>
<Comment.Text>
{notes[0].note.length > 50 ? notes[0].note.slice(0, 50).concat('...')
:
notes[0].note }
</Comment.Text>
</Comment.Content>
</Comment>
:
null
}
</Grid.Column>
<Grid.Column floated='right' width={5} textAlign='right'>
{notes.length > 0 ?
<CommentModal notes={notes} />
:
null}
<Popup
trigger={<Button icon='plus' onClick={this.triggerAdd}/>}
on='click'
position='bottom left'
content={
<Form reply>
<Form.TextArea
value={this.state.note}
onChange={e => this.handleWrite(e)}
/>
<Button
onClick={() => {
this.props.postNote({ eventid:selectedEvent.id,
userid: trainee.id,
note: this.state.note });
this.clearWrite();
}
}
content='Megjegyzés hozzáadása'
labelPosition='left'
icon='edit'
primary
/>
</Form>
}
/>
</Grid.Column>
</Grid.Row>
</Grid>
</Table.Cell>
</Table.Row>
);
}
}
export default connect(() => ({}), { writeNote, clearWrite, postNote, visitorChange, deleteNote })(TraineeTableRow)
import React, { Component } from 'react';
import { Container, Table, Icon } from 'semantic-ui-react';
import { connect } from 'react-redux';
import { getTrainees, getStaffEvents } from '../../actions/statistics';
class Trainees extends Component {
componentWillMount() {
this.props.getTrainees();
this.props.getStaffEvents();
}
renderVisitedStatus(trainee) {
return (this.props.events.map((event) => {
if (event.visitors.includes(trainee.id)) {
return (
<Table.Cell textAlign='center'>
<Icon color='green' name='checkmark' />
</Table.Cell>);
}
return (
<Table.Cell textAlign='center'>
{ event.absent.includes(trainee.id) ?
<Icon color='orange' name='minus' />
:
<Icon color='red' name='cancel' />
}
</Table.Cell>);
}));
}
renderTrainees() {
return this.props.trainees.map((trainee) =>
{ return (
<Table.Row>
<Table.Cell>
{trainee.full_name}
</Table.Cell>
{this.renderVisitedStatus(trainee)}
</Table.Row>
);
});
}
renderTableHeader() {
return (this.props.events.map(event => (
<Table.HeaderCell textAlign='center'>
{event.name}
</Table.HeaderCell>)));
}
render() {
return (
<Container textAlign='center'>
<Table color='blue' selectable compact>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Képződők</Table.HeaderCell>
{ this.renderTableHeader() }
</Table.Row>
</Table.Header>
<Table.Body>
{this.props.trainees ? this.renderTrainees() : 'Nincsenek képződők'}
</Table.Body>
</Table>
</Container>
);
}
}
const mapStateToProps = ({ trainees: { trainees }, events: { events }, user }) => ({ trainees, events, user });
export default connect(mapStateToProps, { getTrainees, getStaffEvents })(Trainees);
import React, { Component } from 'react';
import { Container, Header, Segment } from 'semantic-ui-react';
export default class Trainers extends Component {
render() {
return (
<div>
<Segment inverted textAlign='center' vertical>
<Container>
<Header
as='h1'
content='Képzők - Hamarosan'
inverted
style={{
fontSize: '3em',
fontWeight: 'normal',
marginBottom: 0,
marginTop: '0.5em',
}}
/>
</Container>
</Segment>
</div>
);
}
}
import { createStore, applyMiddleware } from 'redux'; import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger'; // import { createLogger } from 'redux-logger';
import rootReducer from './reducers'; import rootReducer from './reducers';
import thunkMiddleware from 'redux-thunk';
const loggerMiddleware = createLogger(); // const loggerMiddleware = createLogger();
export default function configureStore(preloadedState) { export default function configureStore(preloadedState) {
return createStore( return createStore(
rootReducer, rootReducer,
preloadedState, preloadedState,
applyMiddleware( applyMiddleware(
thunkMiddleware, thunkMiddleware
loggerMiddleware, // loggerMiddleware,
), )
); );
} }
/* eslint-disable import/no-unresolved */
/* eslint-disable import/named */
/* eslint-disable import/extensions */
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux';
// eslint-disable-next-line // eslint-disable-next-line
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Todo from '../components/Todo'; import Todo from '../components/Todo';
import { addTodo } from '../actions'; import { addTodo } from '../actions';
import { connect } from 'react-redux';
class TodoContainer extends Component { class TodoContainer extends Component {
render() { render() {
...@@ -11,13 +15,11 @@ class TodoContainer extends Component { ...@@ -11,13 +15,11 @@ class TodoContainer extends Component {
return ( return (
<div> <div>
{ {todos.map((todo) => (
todos.map(todo => ( <Todo onClick={onTodoClick} key={Math.random()}>
<Todo onClick={onTodoClick} key={Math.random()}> {todo.data}
{todo.data} </Todo>
</Todo> ))}
))
}
</div> </div>
); );
} }
...@@ -31,7 +33,7 @@ const mapStateToProps = (state) => { ...@@ -31,7 +33,7 @@ const mapStateToProps = (state) => {
}; };
}; };
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = (dispatch) => ({
onTodoClick: (data) => { onTodoClick: (data) => {
dispatch(addTodo(data)); dispatch(addTodo(data));
}, },
......
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter as Router } from 'react-router-dom';
import 'slick-carousel/slick/slick.css'; import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css'; import 'slick-carousel/slick/slick-theme.css';
import 'semantic-ui-css/semantic.min.css'; import 'semantic-ui-css/semantic.min.css';
import ScrollToTop from './components/ScrollToTop';
import moment from 'moment';
import configureStore from './configureStore'; import * as serviceWorker from './registerServiceWorker';
import App from './components/App';
import App from './components/App';
import { Provider } from 'react-redux';
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import configureStore from './configureStore';
import moment from 'moment';
import { render } from 'react-dom';
moment.locale(); moment.locale();
...@@ -19,10 +19,10 @@ const store = configureStore(); ...@@ -19,10 +19,10 @@ const store = configureStore();
render( render(
<Provider store={store}> <Provider store={store}>
<Router> <Router>
<ScrollToTop> <App />
<App />
</ScrollToTop>
</Router> </Router>
</Provider>, </Provider>,
document.getElementById('root'), document.getElementById('root')
); );
serviceWorker.unregister();
import { WRITE_NEWS, CLEAR_WRITE } from '../actions/types'; import { CLEAR_WRITE, WRITE_NEWS } from '../actions/types';
const INITIAL_STATE = { title: '', text: '' }; const INITIAL_STATE = { title: '', text: '' };
......
import { WRITE_SOLUTION, WRITE_SOLUTION_FILE, GET_SOLUTIONS, CLEAR_WRITE } from '../actions/types'; import {
CLEAR_WRITE,
GET_SOLUTIONS,
WRITE_SOLUTION,
WRITE_SOLUTION_FILE,
} from '../actions/types';
const INITIAL_STATE = { const INITIAL_STATE = {
task: '', task: '',
......
import { WRITE_TASK, WRITE_TASK_DEADLINE, CLEAR_WRITE } from '../actions/types'; import { CLEAR_WRITE, WRITE_TASK, WRITE_TASK_DEADLINE } from '../actions/types';
const INITIAL_STATE = { title: '', text: '', deadline: '' }; const INITIAL_STATE = { title: '', text: '', deadline: '' };
......
import { WRITE_SOLUTION, CHECK, CLEAR_WRITE } from '../actions/types'; import {
CHECK,
CLEAR_WRITE,
SELECT_SOLUTION,
SETCHECKTRUE,
WRITE_SOLUTION,
} from '../actions/types';
const INITIAL_STATE = { const INITIAL_STATE = {
accepted: false, accepted: false,
corrected: false,
note: '', note: '',
}; };
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
switch (action.type) { switch (action.type) {
case SELECT_SOLUTION:
return {
corrected: action.payload.corrected,
accepted: action.payload.accepted,
note: action.payload.note,
};
case WRITE_SOLUTION: case WRITE_SOLUTION:
return { ...state, [action.target]: action.payload }; return { ...state, [action.target]: action.payload };
case CHECK: case CHECK:
return { ...state, accepted: !state.accepted }; return {
...state,
[action.target]: !state[action.target],
};
case SETCHECKTRUE:
return {
...state,
[action.target]: true,
};
case CLEAR_WRITE: case CLEAR_WRITE:
return INITIAL_STATE; return INITIAL_STATE;
default: default:
......
import { WRITE_NEWS, CLEAR_WRITE, SELECT_NEWS } from '../actions/types'; import { CLEAR_WRITE, SELECT_NEWS, WRITE_NEWS } from '../actions/types';
const INITIAL_STATE = { }; const INITIAL_STATE = {};
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
switch (action.type) { switch (action.type) {
......
import { SELECT_TASK, WRITE_TASK, WRITE_TASK_DEADLINE, CLEAR_WRITE } from '../actions/types'; import {
CLEAR_WRITE,
SELECT_TASK,
WRITE_TASK,
WRITE_TASK_DEADLINE,
} from '../actions/types';
const INITIAL_STATE = { }; const INITIAL_STATE = {};
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
switch (action.type) { switch (action.type) {
......
import { import {
ABSENT_CHANGE,
ADD_EVENT,
CHANGE_NO,
CLEAR_WRITE,
DELETE_EVENT,
GET_EVENTS, GET_EVENTS,
GET_EVENT_BY_ID, GET_EVENT_BY_ID,
VISITOR_CHANGE, VISITOR_CHANGE,
WRITE_EVENT, WRITE_EVENT,
ADD_EVENT,
DELETE_EVENT,
CLEAR_WRITE,
ABSENT_CHANGE,
CHANGE_NO,
SELECT_EVENT_FOR_EDIT,
EDIT_EVENT,
WRITE_EDITED_EVENT,
} from '../actions/types'; } from '../actions/types';
const INITIAL_STATE = { events: [], newEvent: {}, editedEvent: {} }; const INITIAL_STATE = { events: [], newEvent: {} };
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
switch (action.type) { switch (action.type) {
...@@ -24,13 +21,16 @@ export default (state = INITIAL_STATE, action) => { ...@@ -24,13 +21,16 @@ export default (state = INITIAL_STATE, action) => {
case VISITOR_CHANGE: case VISITOR_CHANGE:
if (state.selectedEvent.visitors.includes(action.payload)) { if (state.selectedEvent.visitors.includes(action.payload)) {
// Benne van nem kell megváltoztatni // Benne van nem kell megváltoztatni
return { ...state } return { ...state };
} }
if (state.selectedEvent.absent.indexOf(action.payload) > -1) { if (state.selectedEvent.absent.indexOf(action.payload) > -1) {
// Ha az absentbe van ki kell venni // Ha az absentbe van ki kell venni
state.selectedEvent.absent.splice(state.selectedEvent.absent.indexOf(action.payload), 1); state.selectedEvent.absent.splice(
state.selectedEvent.absent.indexOf(action.payload),
1
);
} }
state.selectedEvent.visitors.push(action.payload) state.selectedEvent.visitors.push(action.payload);
return { return {
...state, ...state,
selectedEvent: { selectedEvent: {
...@@ -44,7 +44,10 @@ export default (state = INITIAL_STATE, action) => { ...@@ -44,7 +44,10 @@ export default (state = INITIAL_STATE, action) => {
return { ...state }; return { ...state };
} }
if (state.selectedEvent.visitors.indexOf(action.payload) > -1) { if (state.selectedEvent.visitors.indexOf(action.payload) > -1) {
state.selectedEvent.visitors.splice(state.selectedEvent.visitors.indexOf(action.payload), 1); state.selectedEvent.visitors.splice(
state.selectedEvent.visitors.indexOf(action.payload),
1
);
} }
state.selectedEvent.absent.push(action.payload); state.selectedEvent.absent.push(action.payload);
return { return {
...@@ -57,11 +60,17 @@ export default (state = INITIAL_STATE, action) => { ...@@ -57,11 +60,17 @@ export default (state = INITIAL_STATE, action) => {
}; };
case CHANGE_NO: case CHANGE_NO:
if (state.selectedEvent.visitors.indexOf(action.payload) > -1) { if (state.selectedEvent.visitors.indexOf(action.payload) > -1) {
state.selectedEvent.visitors.splice(state.selectedEvent.visitors.indexOf(action.payload), 1); state.selectedEvent.visitors.splice(
state.selectedEvent.visitors.indexOf(action.payload),
1
);
} }
if (state.selectedEvent.absent.indexOf(action.payload) > -1) { if (state.selectedEvent.absent.indexOf(action.payload) > -1) {
// Ha az absentbe van ki kell venni // Ha az absentbe van ki kell venni
state.selectedEvent.absent.splice(state.selectedEvent.absent.indexOf(action.payload), 1); state.selectedEvent.absent.splice(
state.selectedEvent.absent.indexOf(action.payload),
1
);
} }
return { return {
...state, ...state,
...@@ -72,22 +81,17 @@ export default (state = INITIAL_STATE, action) => { ...@@ -72,22 +81,17 @@ export default (state = INITIAL_STATE, action) => {
}, },
}; };
case WRITE_EVENT: case WRITE_EVENT:
return { ...state, newEvent: { ...state.newEvent, [action.target]: action.payload } }; return {
...state,
newEvent: { ...state.newEvent, [action.target]: action.payload },
};
case ADD_EVENT: case ADD_EVENT:
return { ...state, events: [...state.events, action.payload] }; return { ...state, events: [...state.events, action.payload] };
case DELETE_EVENT: case DELETE_EVENT:
state.events.splice(state.events.indexOf(action.payload), 1); state.events.splice(state.events.indexOf(action.payload), 1);
return { ...state, events: [...state.events] }; return { ...state, events: [...state.events] };
case SELECT_EVENT_FOR_EDIT:
return { ...state, editedEvent: action.payload }
case WRITE_EDITED_EVENT:
return { ...state, editedEvent: { ...state.editedEvent, [action.target]: action.payload } };
case EDIT_EVENT:
const index = state.events.findIndex(item => item.id === action.payload.id);
state.events.splice(index, 1, action.payload);
return { ...state, events: [...state.events] };
case CLEAR_WRITE: case CLEAR_WRITE:
return { ...state, newEvent: {}, editedEvent: {} }; return { ...state, newEvent: {} };
default: default:
return state; return state;
} }
......
import { GET_GROUPS } from '../actions/types';
const INITIAL_STATE = [];
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_GROUPS:
return action.payload;
default:
return state;
}
};