|
@@ -1,7 +1,15 @@
|
|
|
import React, {useState} from "react";
|
|
|
import axios from "axios";
|
|
|
+import DateFnsUtils from '@date-io/date-fns';
|
|
|
+import {nb} from 'date-fns/locale'
|
|
|
+import {DateTimePicker, MuiPickersUtilsProvider} from '@material-ui/pickers';
|
|
|
+import {makeStyles} from '@material-ui/core/styles';
|
|
|
+
|
|
|
+import ReCAPTCHA from "react-google-recaptcha";
|
|
|
+
|
|
|
import {
|
|
|
Button,
|
|
|
+ ButtonGroup,
|
|
|
Container,
|
|
|
Checkbox,
|
|
|
CssBaseline,
|
|
@@ -9,20 +17,26 @@ import {
|
|
|
DialogTitle,
|
|
|
DialogContent,
|
|
|
DialogActions,
|
|
|
- Grid,
|
|
|
FormControl,
|
|
|
FormControlLabel,
|
|
|
FormGroup,
|
|
|
+ Grid,
|
|
|
+ IconButton,
|
|
|
Paper,
|
|
|
TextField,
|
|
|
Typography,
|
|
|
} from '@material-ui/core';
|
|
|
-import {makeStyles} from '@material-ui/core/styles';
|
|
|
+
|
|
|
+import {
|
|
|
+ Add,
|
|
|
+ Remove,
|
|
|
+} from '@material-ui/icons'
|
|
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
|
fieldset: {
|
|
|
//border: 'none',
|
|
|
- //borderBottom: '1px solid',
|
|
|
+ marginBottom: theme.spacing(3),
|
|
|
+ paddingBottom: theme.spacing(3),
|
|
|
},
|
|
|
form: {
|
|
|
width: '100%',
|
|
@@ -37,107 +51,303 @@ const useStyles = makeStyles((theme) => ({
|
|
|
}
|
|
|
}));
|
|
|
|
|
|
+const SubmitButton = (props) => {
|
|
|
+
|
|
|
+ const [isApproved, setIsApproved] = useState(false);
|
|
|
+ const recaptchaRef = React.createRef();
|
|
|
+
|
|
|
+ const onChange = (value) => {
|
|
|
+ console.log("Captcha value:", value);
|
|
|
+ setIsApproved(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <React.Fragment>
|
|
|
+ <center>
|
|
|
+ <ReCAPTCHA
|
|
|
+ onChange={onChange}
|
|
|
+ onExpired={() => isApproved ? setIsApproved(false) : false}
|
|
|
+ ref={recaptchaRef}
|
|
|
+ sitekey={"6LfRxgAVAAAAALlMOyD5h_a6gvWulxGqCC5gKJvd"}
|
|
|
+ size={"invisible"}
|
|
|
+ />
|
|
|
+ </center>
|
|
|
+ <Button
|
|
|
+ color={"primary"}
|
|
|
+ variant={"contained"}
|
|
|
+ fullWidth
|
|
|
+ type={"submit"}
|
|
|
+ onClick={(e) => {
|
|
|
+ recaptchaRef.current.execute();
|
|
|
+ }}
|
|
|
+ >Send skjema</Button>
|
|
|
+ </React.Fragment>
|
|
|
+ );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
const RegForm = (props) => {
|
|
|
const classes = useStyles();
|
|
|
+
|
|
|
+ const [inputs, updateInputs] = useState({
|
|
|
+ dates: [{date: new Date(), duration: 0}],
|
|
|
+ });
|
|
|
+
|
|
|
+ const inputHandler = (event) => {
|
|
|
+ const target = event.target
|
|
|
+ updateInputs((prevState) => ({...prevState, [target.id]: target.value}));
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ const inputCategoryHandler = (type, event, category) => {
|
|
|
+ const keys = Object.keys(inputs).filter(idx => idx == type);
|
|
|
+ let arr = keys.length == 0 ? [] : inputs[keys[0]];
|
|
|
+
|
|
|
+ if (event.target.checked)
|
|
|
+ arr.push(category);
|
|
|
+ else
|
|
|
+ arr = arr.filter(item => item.id != category.id);
|
|
|
+
|
|
|
+ updateInputs((prevState) => ({...prevState, [type]: arr}));
|
|
|
+ }
|
|
|
+
|
|
|
+ const dateAddHandler = (idx) => {
|
|
|
+ inputs.dates.splice(idx, 0, {...inputs.dates[idx]});
|
|
|
+ updateInputs((prevState) => ({...prevState, dates: inputs.dates}));
|
|
|
+ }
|
|
|
+
|
|
|
+ const dateRemoveHandler = (idx) => {
|
|
|
+ if (inputs.dates.length == 1)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!inputs.dates[idx])
|
|
|
+ return;
|
|
|
+
|
|
|
+ updateInputs(prevState => ({...prevState, dates: [...inputs.dates.slice(0, idx), ...inputs.dates.slice(idx+1)]}));
|
|
|
+ }
|
|
|
+
|
|
|
+ const dateSaveHandler = (idx, e) => {
|
|
|
+ if (!inputs.dates[idx])
|
|
|
+ return;
|
|
|
+ inputs.dates[idx].date = e;
|
|
|
+ updateInputs((prevState) => ({...prevState, dates: inputs.dates}));
|
|
|
+ }
|
|
|
+
|
|
|
+ const dateDurationSaveHandler = (idx, e) => {
|
|
|
+ if (!inputs.dates[idx])
|
|
|
+ return;
|
|
|
+
|
|
|
+ const target = e.target;
|
|
|
+ inputs.dates[idx].duration = parseInt(target.value, 10);
|
|
|
+
|
|
|
+ updateInputs((prevState) => ({...prevState, dates: inputs.dates}));
|
|
|
+ }
|
|
|
+
|
|
|
+ const submitHandler = (event) => {
|
|
|
+ event.PreventDefault();
|
|
|
+ console.log(event);
|
|
|
+ }
|
|
|
+
|
|
|
return (
|
|
|
<Container component="main" maxWidth="md">
|
|
|
<CssBaseline />
|
|
|
<Paper className={classes.paper}>
|
|
|
- <Typography component={"h1"} variant={"h5"}>
|
|
|
- Registrer ditt event
|
|
|
- </Typography>
|
|
|
<form className={classes.form}>
|
|
|
<FormControl component={"fieldset"} className={classes.fieldset}>
|
|
|
- <Grid container spacing={3}>
|
|
|
- <Grid item xs={12}>
|
|
|
- <TextField
|
|
|
- id={"organizer"}
|
|
|
- label={"Arrangør"}
|
|
|
- name={"organizer"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
- required
|
|
|
- fullWidth
|
|
|
- autoFocus
|
|
|
- />
|
|
|
- </Grid>
|
|
|
- <Grid item xs={12} sm={4}>
|
|
|
- <TextField
|
|
|
- id={"contact_name"}
|
|
|
- label={"Kontakt person"}
|
|
|
- name={"contact_name"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
- required
|
|
|
- fullWidth
|
|
|
- />
|
|
|
- </Grid>
|
|
|
- <Grid item xs={12} sm={4}>
|
|
|
- <TextField
|
|
|
- id={"contact_email"}
|
|
|
- label={"Epostadresse"}
|
|
|
- name={"contact_email"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
- type={"email"}
|
|
|
- required
|
|
|
- fullWidth
|
|
|
- />
|
|
|
- </Grid>
|
|
|
- <Grid item xs={12} sm={4}>
|
|
|
- <TextField
|
|
|
- id={"contact_phone"}
|
|
|
- label={"Telefonnummer"}
|
|
|
- name={"contact_phone"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
- type={"tel"}
|
|
|
- required
|
|
|
- fullWidth
|
|
|
- />
|
|
|
+ <Typography component={"legend"} variant={"h5"}>
|
|
|
+ Om arrangøren
|
|
|
+ </Typography>
|
|
|
+ <Grid container spacing={3}>
|
|
|
+ <Grid item xs={12} sm={7} md={8}>
|
|
|
+ <TextField
|
|
|
+ id={"organizer"}
|
|
|
+ label={"Navn på arrangør"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ autoFocus
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={5} md={4}>
|
|
|
+ <TextField
|
|
|
+ id={"organization_number"}
|
|
|
+ label={"Org.nummer"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id={"contact_name"}
|
|
|
+ label={"Kontakt person"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id={"contact_email"}
|
|
|
+ label={"Epostadresse"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ type={"email"}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id={"contact_phone"}
|
|
|
+ label={"Telefonnummer"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ type={"tel"}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id={"contact_homepage"}
|
|
|
+ label={"Hjemmesideadresse"}
|
|
|
+ placeholder={"https:// ...."}
|
|
|
+ required
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
</Grid>
|
|
|
- </Grid>
|
|
|
</FormControl>
|
|
|
<FormControl component={"fieldset"} className={classes.fieldset}>
|
|
|
- <legend>Arrangement</legend>
|
|
|
+ <Typography component={"legend"} variant={"h5"}>
|
|
|
+ Om arrangementet
|
|
|
+ </Typography>
|
|
|
<Grid container spacing={3}>
|
|
|
- <Grid item xs={12} sm={8}>
|
|
|
+ <Grid item xs={12}>
|
|
|
<TextField
|
|
|
id={"event_name"}
|
|
|
label={"Navn på arrangement"}
|
|
|
- name={"event_name"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
+ onChange={inputHandler}
|
|
|
required
|
|
|
fullWidth
|
|
|
/>
|
|
|
</Grid>
|
|
|
+ {inputs.dates.map((date, idx) => (
|
|
|
+ <React.Fragment key={idx}>
|
|
|
+ <Grid item xs={6}>
|
|
|
+ <MuiPickersUtilsProvider utils={DateFnsUtils} locale={nb}>
|
|
|
+ <DateTimePicker
|
|
|
+ fullWidth
|
|
|
+ format={"do MMMM y HH:mm (h:mm a)"}
|
|
|
+ ampm={false}
|
|
|
+ value={date.date}
|
|
|
+ onChange={e => dateSaveHandler(idx, e)}
|
|
|
+ margin={"normal"}
|
|
|
+ />
|
|
|
+ </MuiPickersUtilsProvider>
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={4}>
|
|
|
+ <TextField
|
|
|
+ id={"event_duration"}
|
|
|
+ label={"Varighet (timer)"}
|
|
|
+ onChange={e => dateDurationSaveHandler(idx, e)}
|
|
|
+ type={"number"}
|
|
|
+ placeholder={"antall timer"}
|
|
|
+ value={date.duration}
|
|
|
+ fullWidth
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={1}>
|
|
|
+ <IconButton onClick={() => dateAddHandler(idx)}><Add /></IconButton>
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={1}>
|
|
|
+ <IconButton onClick={() => dateRemoveHandler(idx)}><Remove /></IconButton>
|
|
|
+ </Grid>
|
|
|
+ </React.Fragment>
|
|
|
+ ))}
|
|
|
+ <Grid item xs={12} sm={8}>
|
|
|
+ <TextField
|
|
|
+ id={'event_location'}
|
|
|
+ label={"Sted"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ placeholder={"Hvor skjer arrangementet?"}
|
|
|
+ fullWidth
|
|
|
+ required
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
<Grid item xs={12} sm={4}>
|
|
|
<TextField
|
|
|
id={"event_capacity"}
|
|
|
label={"Kapasitet"}
|
|
|
- name={"event_capacity"}
|
|
|
- variant={"outlined"}
|
|
|
- margin={"normal"}
|
|
|
+ placeholder={"Antall personer"}
|
|
|
+ onChange={inputHandler}
|
|
|
type={"number"}
|
|
|
required
|
|
|
fullWidth
|
|
|
/>
|
|
|
</Grid>
|
|
|
+ <Grid item xs={12}>
|
|
|
+ <TextField
|
|
|
+ id={"event_description"}
|
|
|
+ label={"Beskrivelse av arrangement"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ placeholder={"Forklar detaljert om ditt arrangement - dette skal besøkende lese!"}
|
|
|
+ multiline
|
|
|
+ fullWidth
|
|
|
+ required
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id="event_photo"
|
|
|
+ label={"Photo-link til arrangement"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ placeholder={"Kan for eks. være en bilde-fil eller mappe med bilder i Dropbox."}
|
|
|
+ fullWidth
|
|
|
+ required
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
+ <Grid item xs={12} sm={6}>
|
|
|
+ <TextField
|
|
|
+ id="event_booking"
|
|
|
+ label={"Link til booking"}
|
|
|
+ onChange={inputHandler}
|
|
|
+ placeholder={"https:// ..."}
|
|
|
+ fullWidth
|
|
|
+ required
|
|
|
+ />
|
|
|
+ </Grid>
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
- <Categories cid={"5ed0f77a42f75848a95ebf03"} />
|
|
|
+ <CategorySelection
|
|
|
+ cid={"5ed0f77a42f75848a95ebf03"}
|
|
|
+ category="Kategorier"
|
|
|
+ name="categories"
|
|
|
+ selected={inputs.categories || []}
|
|
|
+ inputCategoryHandler={inputCategoryHandler}
|
|
|
+ />
|
|
|
</Grid>
|
|
|
<Grid item xs={12} sm={6}>
|
|
|
+ <CategorySelection
|
|
|
+ cid={"5ed10cffd2b21cfb3b269088"}
|
|
|
+ category="Målgrupper"
|
|
|
+ name="audiences"
|
|
|
+ selected={inputs.audiences || []}
|
|
|
+ inputCategoryHandler={inputCategoryHandler}
|
|
|
+ />
|
|
|
</Grid>
|
|
|
</Grid>
|
|
|
</FormControl>
|
|
|
+ <Grid container justify={"center"}>
|
|
|
+ <Grid item xs={8}>
|
|
|
+ <SubmitButton text={"Send skjema"}/>
|
|
|
+ </Grid>
|
|
|
+ </Grid>
|
|
|
</form>
|
|
|
</Paper>
|
|
|
</Container>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-const Categories = (props) => {
|
|
|
+const CategorySelection = (props) => {
|
|
|
const [error, setError] = useState(null);
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
const [availableItems, setAvailableItems] = useState([]);
|
|
@@ -146,41 +356,46 @@ const Categories = (props) => {
|
|
|
axios.get("https://magy.giaever.online/tff/api/webflow_items?cid=" + props.cid)
|
|
|
.then((response) => {
|
|
|
const data = response.data['hydra:member'];
|
|
|
- setAvailableItems(data);
|
|
|
+ setAvailableItems(response.data['hydra:member']);
|
|
|
})
|
|
|
.catch((error) => {
|
|
|
- console.log(error);
|
|
|
setError(error);
|
|
|
})
|
|
|
.then(() => {
|
|
|
- console.log("DONE");
|
|
|
setIsLoading(false);
|
|
|
});
|
|
|
}, []);
|
|
|
|
|
|
return (
|
|
|
- <DialogCancelOk
|
|
|
- buttonDesc={isLoading ? "Laster kategorier" : "Velg kategori"}
|
|
|
- buttonDisabled={isLoading}
|
|
|
- dialogTitle={"Velg kategori(er)"}
|
|
|
- >
|
|
|
- {isLoading ?
|
|
|
- <p>
|
|
|
- Laster...
|
|
|
- </p>
|
|
|
- :
|
|
|
- <FormGroup>
|
|
|
- {availableItems.map(item => <FormControlLabel
|
|
|
- key={item.id}
|
|
|
- control={
|
|
|
- <Checkbox checked={false} value={item.id} />
|
|
|
- }
|
|
|
- label={item.name}
|
|
|
- />
|
|
|
- )}
|
|
|
- </FormGroup>
|
|
|
- }
|
|
|
- </DialogCancelOk>
|
|
|
+ <React.Fragment>
|
|
|
+ <DialogCancelOk
|
|
|
+ buttonDesc={isLoading ? `Laster ${props.category}` : `Velg ${props.category}`}
|
|
|
+ buttonDisabled={isLoading}
|
|
|
+ dialogTitle={`Velg ${props.category}`}
|
|
|
+ >
|
|
|
+ {isLoading ?
|
|
|
+ <p>
|
|
|
+ Laster...
|
|
|
+ </p>
|
|
|
+ :
|
|
|
+ <FormGroup>
|
|
|
+ {availableItems.map(item => <FormControlLabel
|
|
|
+ key={item.id}
|
|
|
+ control={
|
|
|
+ <Checkbox
|
|
|
+ checked={props.selected.filter(sitem => sitem.id == item.id).length > 0}
|
|
|
+ value={item.id}
|
|
|
+ onChange={() => props.inputCategoryHandler(props.name, event, item)}
|
|
|
+ />
|
|
|
+ }
|
|
|
+ label={item.name}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </FormGroup>
|
|
|
+ }
|
|
|
+ </DialogCancelOk>
|
|
|
+ <ul>{props.selected.map(item => <li key={item.id}>{item.name}</li>)}</ul>
|
|
|
+ </React.Fragment>
|
|
|
)
|
|
|
}
|
|
|
|
|
@@ -201,7 +416,7 @@ const DialogCancelOk = (props) => {
|
|
|
fullWidth
|
|
|
disabled={props.buttonDisabled}
|
|
|
color={"secondary"}
|
|
|
- variant={"outlined"}
|
|
|
+ variant={props.buttonDisabled ? "outlined" : "contained"}
|
|
|
onClick={handleClickOpen}>
|
|
|
{props.buttonDesc}
|
|
|
</Button>
|