all repos — caroster @ 1cc727f3c230f02f4f837deb8a5d7780737ee2c4

[Octree] Group carpool to your event https://caroster.io

Dashoard setup
Hadrien Froger hadrien@octree.ch
Fri, 17 Jul 2020 17:31:53 +0100
commit

1cc727f3c230f02f4f837deb8a5d7780737ee2c4

parent

ec8b25be9fb27eea5119a512c5b62bc6166a5354

M app/.eslintrcapp/.eslintrc

@@ -34,7 +34,7 @@ }

}, "rules": { "prefer-const": "error", - "complexity": ["warn", 10], + "complexity": ["warn", 16], "max-len": ["warn", 110], "arrow-parens": "off", "prefer-destructuring": "error",
M app/package-lock.jsonapp/package-lock.json

@@ -12303,9 +12303,9 @@ "resolved": "https://npm-8ee.hidora.com/stealthy-require/-/stealthy-require-1.1.1.tgz",

"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "strapi-react-context": { - "version": "0.2.6", - "resolved": "https://npm-8ee.hidora.com/strapi-react-context/-/strapi-react-context-0.2.6.tgz", - "integrity": "sha512-l8iQzVVSfZW8Gxj0ORGv6PskUDeOT3Cb46CCCkLcE7oXRihNCjWuVJAkELQlkZpcvIx2aYGA1cOv0KDAu4e2fQ==", + "version": "0.2.7", + "resolved": "https://npm-8ee.hidora.com/strapi-react-context/-/strapi-react-context-0.2.7.tgz", + "integrity": "sha512-Dp8SfBlGVmSlAitAa7kvAtx0gJH5xLPLN5/lLi8Tjm6gcQepgP3Xny5ouNJZvvY6Pxrp/7x+iXnGFddeLTQUJw==", "requires": { "@testing-library/react-hooks": "^3.3.0" }
M app/package.jsonapp/package.json

@@ -2,7 +2,7 @@ {

"name": "app", "version": "0.1.0", "private": true, - "proxy": "https://caroster.dev.octr.ee", + "proxy": "http://localhost:1337", "dependencies": { "@date-io/moment": "^1.3.13", "@material-ui/core": "^4.10.2",

@@ -23,7 +23,7 @@ "react-leaflet": "^2.7.0",

"react-router-dom": "^5.2.0", "react-scripts": "3.4.1", "react-slick": "^0.26.1", - "strapi-react-context": "^0.2.6" + "strapi-react-context": "^0.2.7" }, "scripts": { "start": "react-scripts start",
M app/src/containers/AddToMyEventDialog/AddToMyEventDialog.jsapp/src/containers/AddToMyEventDialog/AddToMyEventDialog.js

@@ -7,13 +7,14 @@ import DialogTitle from '@material-ui/core/DialogTitle';

import Slide from '@material-ui/core/Slide'; import Button from '@material-ui/core/Button'; import {useTranslation} from 'react-i18next'; - +import {useHistory} from 'react-router-dom'; const Transition = React.forwardRef(function Transition(props, ref) { return <Slide direction="up" ref={ref} {...props} />; }); const AddToMyEventDialog = ({event, open, onClose}) => { const {t} = useTranslation(); + const history = useHistory(); return ( <Dialog open={open} TransitionComponent={Transition} onClose={onClose}> <DialogContent>

@@ -32,10 +33,27 @@ <DialogActions>

<Button onClick={onClose} id="AddToMyEventCancel"> {t('event.add_to_my_events.cancel')} </Button> - <Button id="AddToMyEventLogin" href="/login"> + <Button + id="AddToMyEventLogin" + onClick={() => { + history.push({ + pathName: '/login', + state: {event: event.id}, + }); + }} + > {t('event.add_to_my_events.login')} </Button> - <Button id="AddToMyEventRegister" href="/register" color="primary"> + <Button + id="AddToMyEventRegister" + onClick={() => { + history.push({ + pathName: '/register', + state: {event: event.id}, + }); + }} + color="primary" + > {t('event.add_to_my_events.register')} </Button> </DialogActions>
M app/src/containers/Car/index.jsapp/src/containers/Car/index.js

@@ -6,6 +6,7 @@ import {useTranslation} from 'react-i18next';

import {useStrapi} from 'strapi-react-context'; import {useEvent} from '../../contexts/Event'; import {useToast} from '../../contexts/Toast'; +import useProfile from '../../hooks/useProfile'; import PassengersList from '../PassengersList'; import HeaderEditing from './HeaderEditing'; import Header from './Header';

@@ -13,9 +14,10 @@

const Car = ({car}) => { const classes = useStyles(); const {t} = useTranslation(); + const strapi = useStrapi(); const {event} = useEvent(); + const {addEvent} = useProfile(); const {addToast} = useToast(); - const strapi = useStrapi(); const [isEditing, toggleEditing] = useReducer(i => !i, false); if (!car) return null;

@@ -25,25 +27,25 @@ try {

await strapi.services.cars.update(car.id, { passengers: [...(car.passengers || []), passenger], }); + addEvent(event); } catch (error) { console.error(error); - addToast(t('car.errors.cant_add_passenger')); } }; const removePassenger = async idx => { - if (!car?.passengers) return false; - try { - await strapi.services.events.update(event.id, { - waiting_list: [...(event.waiting_list || []), car.passengers[idx]], - }); - return await strapi.services.cars.update(car.id, { - passengers: car.passengers.filter((_, i) => i !== idx), - }); - } catch (error) { - console.error(error); - addToast(t('car.errors.cant_remove_passenger')); - return false; + if (car?.passengers) { + try { + await strapi.services.events.update(event.id, { + waiting_list: [...(event.waiting_list || []), car.passengers[idx]], + }); + await strapi.services.cars.update(car.id, { + passengers: car.passengers.filter((_, i) => i !== idx), + }); + } catch (error) { + console.error(error); + addToast(t('car.errors.cant_remove_passenger')); + } } };
M app/src/containers/PassengersList/index.jsapp/src/containers/PassengersList/index.js

@@ -9,9 +9,8 @@ import Input from './Input';

import Passenger from './Passenger'; const PassengersList = ({ - hideEmpty, passengers, - places = 0, + places, addPassenger, icon, onClick,

@@ -22,14 +21,12 @@ const classes = useStyles();

let list = passengers; - if (!hideEmpty) { + if (!!places) { const emptyList = [...Array(places)]; list = Array.isArray(passengers) ? emptyList.map((u, index) => passengers[index]) : emptyList; } - - const emptyPlaces = !!passengers ? places - passengers.length : places; const button = index => { return !!onClick ? (

@@ -45,10 +42,13 @@ };

return ( <div className={classes.container}> - {emptyPlaces > 0 && <Input addPassenger={addPassenger} />} + {(!!places + ? !!passengers + ? places - passengers.length > 0 + : places > 0 + : true) && <Input addPassenger={addPassenger} />} <List disablePadding> - {!!places && - !!list && + {!!list && list.map((passenger, index) => ( <ListItem key={index}
M app/src/containers/SignIn/SignIn.test.jsapp/src/containers/SignIn/SignIn.test.js

@@ -1,6 +1,7 @@

import React from 'react'; import renderer from 'react-test-renderer'; import SignIn from './SignIn'; + describe('SignIn', () => { const signIn = renderer.create(<SignIn />); it('match snapshot without props', () => {
M app/src/containers/SignUp/SignUp.jsapp/src/containers/SignUp/SignUp.js

@@ -1,4 +1,4 @@

-import React, {useCallback, useState, useMemo} from 'react'; +import React, {useState, useMemo} from 'react'; import {useTranslation} from 'react-i18next'; import {useAuth} from 'strapi-react-context'; import TextField from '@material-ui/core/TextField';

@@ -9,11 +9,16 @@ import {useToast} from '../../contexts/Toast';

import {Redirect} from 'react-router-dom'; import {CircularProgress} from '@material-ui/core'; import {makeStyles} from '@material-ui/core/styles'; +import {useHistory} from 'react-router-dom'; const SignUp = () => { const {t} = useTranslation(); const classes = useStyles(); - + const history = useHistory(); + const { + location: {state: historyState = {}}, + } = history; + console.log({event: historyState.event}); const {signUp, token} = useAuth(); const [isLoading, setIsLoading] = useState(false); const [firstName, setFirstName] = useState('');

@@ -29,32 +34,30 @@ [firstName, lastName, email, password]

); const {addToast} = useToast(); - const onSubmit = useCallback( - async evt => { - if (evt.preventDefault) evt.preventDefault(); - if (isLoading) return; - setIsLoading(true); - try { - await signUp(email.replace(/\.@/, '_'), email, password, { - firstName, - lastName, - }); - } catch (error) { - if (error.kind && error.kind === 'bad_data') - addToast(t('signup.errors.email_taken')); - else if (error.kind) { - addToast(t(`generic.errors.${error.kind}`)); - } else { - addToast(t(`generic.errors.unknown`)); - } + const onSubmit = async evt => { + if (evt.preventDefault) evt.preventDefault(); + if (isLoading) return; + setIsLoading(true); + try { + await signUp(email.replace(/\.@/, '_'), email, password, { + firstName, + lastName, + events: historyState.event ? [historyState.event] : [], + }); + } catch (error) { + if (error.kind && error.kind === 'bad_data') + addToast(t('signup.errors.email_taken')); + else if (error.kind) { + addToast(t(`generic.errors.${error.kind}`)); + } else { + addToast(t(`generic.errors.unknown`)); } - setIsLoading(false); - return false; - }, - [firstName, lastName, email, password, addToast, signUp, t, isLoading] - ); + } + setIsLoading(false); + return false; + }; - if (!!token) { + if (!!token && !isLoading) { return <Redirect to="/register/success" />; }

@@ -116,7 +119,11 @@ id="SignUpSubmit"

> {t('signup.submit')} {isLoading && ( - <CircularProgress class={classes.loader} size={20} color="white" /> + <CircularProgress + class={classes.loader} + size={20} + color="secondary" + /> )} </Button> <Button id="SignUpLogin" href="/login">
M app/src/containers/SignUp/SignUp.test.jsapp/src/containers/SignUp/SignUp.test.js

@@ -1,6 +1,7 @@

import React from 'react'; import renderer from 'react-test-renderer'; import SignUp from './SignUp'; + describe('SignUp', () => { const signUpNode = renderer.create(<SignUp />); it('match snapshot without props', () => {
M app/src/containers/WaitingList/index.jsapp/src/containers/WaitingList/index.js

@@ -1,4 +1,4 @@

-import React, {useReducer, useState, useEffect, useMemo} from 'react'; +import React, {useReducer, useState, useMemo, useCallback} from 'react'; import Typography from '@material-ui/core/Typography'; import IconButton from '@material-ui/core/IconButton'; import Icon from '@material-ui/core/Icon';

@@ -23,10 +23,9 @@

const WaitingList = ({car}) => { const classes = useStyles(); const {t} = useTranslation(); + const strapi = useStrapi(); const {event} = useEvent(); const {addToast} = useToast(); - const strapi = useStrapi(); - const [passengers, setPassengers] = useState(event.waiting_list); const [isEditing, toggleEditing] = useReducer(i => !i, false); const [removing, setRemoving] = useState(null); const [adding, setAdding] = useState(null);

@@ -46,58 +45,65 @@ return count + seats - passengers.length;

}, 0); }, [cars]); - useEffect(() => { - setPassengers(event.waiting_list); - }, [event.waiting_list]); - - const addPassenger = async passenger => { - try { - await strapi.services.events.update(event.id, { - waiting_list: [...(event.waiting_list || []), passenger], - }); - } catch (error) { - console.error(error); - addToast(t('passenger.errors.cant_add_passenger')); - } - }; - - const removePassenger = index => { - setPassengers(passengers.filter((_, i) => i !== index)); - }; + const saveWaitingList = useCallback( + async (waitingList, i18nError) => { + try { + await strapi.services.events.update(event.id, { + waiting_list: waitingList, + }); + } catch (error) { + console.error(error); + addToast(t(i18nError)); + } + }, + [event] // eslint-disable-line + ); - const savePassengers = async () => { - try { - await strapi.services.events.update(event.id, {waiting_list: passengers}); - } catch (error) { - console.error(error); - addToast(t('passenger.errors.cant_save_passengers')); - } - }; + const addPassenger = useCallback( + async passenger => { + return saveWaitingList( + [...(event.waiting_list || []), passenger], + 'passenger.errors.cant_add_passenger' + ); + }, + [event] // eslint-disable-line + ); - const selectCar = async car => { - try { - await strapi.services.cars.update(car.id, { - passengers: [...(car.passengers || []), passengers[adding]], - }); - await strapi.services.events.update(event.id, { - waiting_list: event.waiting_list.filter((_, i) => i !== adding), - }); - } catch (error) { - console.error(error); - addToast(t('passenger.errors.cant_select_car')); - } - setAdding(null); - }; + const removePassenger = useCallback( + async index => { + return saveWaitingList( + event.waiting_list.filter((_, i) => i !== index), + 'passenger.errors.cant_remove_passenger' + ); + }, + [event] // eslint-disable-line + ); - const onEdit = () => { - if (isEditing) savePassengers(); - toggleEditing(); - }; + const selectCar = useCallback( + async car => { + try { + await strapi.services.cars.update(car.id, { + passengers: [...(car.passengers || []), event.waiting_list[adding]], + }); + await strapi.services.events.update(event.id, { + waiting_list: event.waiting_list.filter((_, i) => i !== adding), + }); + } catch (error) { + console.error(error); + addToast(t('passenger.errors.cant_select_car')); + } + setAdding(null); + }, + [event, adding] // eslint-disable-line + ); - const onPress = index => { - if (isEditing) setRemoving(index); - else setAdding(index); - }; + const onPress = useCallback( + index => { + if (isEditing) setRemoving(index); + else setAdding(index); + }, + [isEditing] + ); return ( <>

@@ -107,7 +113,7 @@ <IconButton

size="small" color="primary" className={classes.editBtn} - onClick={onEdit} + onClick={toggleEditing} > {isEditing ? <Icon>check</Icon> : <Icon>edit</Icon>} </IconButton>

@@ -118,20 +124,20 @@ </Typography>

</div> <Divider /> <PassengersList - hideEmpty - places={50} - passengers={passengers} + passengers={event.waiting_list} addPassenger={addPassenger} onPress={onPress} icon={isEditing ? 'close' : 'chevron_right'} - disabled={availability <= 0} + disabled={!isEditing && availability <= 0} /> </Paper> <RemoveDialog text={ <Trans i18nKey="passenger.actions.remove_alert" - values={{name: passengers ? passengers[removing] : null}} + values={{ + name: event.waiting_list ? event.waiting_list[removing] : null, + }} components={{italic: <i />, bold: <strong />}} /> }
A app/src/hooks/useProfile.js

@@ -0,0 +1,26 @@

+import {useEffect, useState} from 'react'; +import {useAuth} from 'strapi-react-context'; + +export default () => { + const {token, authState, updateProfile} = useAuth(); + const [connected, setConnected] = useState(false); + + useEffect(() => { + setConnected(!!token); + }, [token]); + + const addEvent = async event => { + if (connected) { + const {user} = authState; + const {events} = user; + updateProfile({ + ...user, + events: !!events + ? [...events.filter(e => e !== event.id), event.id] + : [event.id], + }); + } + }; + + return {connected, addEvent}; +};
M app/src/locales/fr.jsonapp/src/locales/fr.json

@@ -44,8 +44,8 @@ "copied": "Le lien a été copié dans votre presse-papier",

"add_to_my_events": "Ajouter à mes évènements", "my_events": "Mes évènements", "signin": "Se connecter", - "signup": "S'inscrire" - + "signup": "S'inscrire", + "my_profile": "Profil" }, "errors": { "cant_create": "Impossible de créer l'événement",

@@ -107,6 +107,7 @@ },

"errors": { "cant_add_passenger": "Impossible d'ajouter un passager", "cant_save_passengers": "Impossible de mettre à jour passagers", + "cant_remove_passenger": "Impossible de retirer le passager", "cant_select_car": "Impossible de sélectionner la voiture" } },
M app/src/pages/Dashboard.jsapp/src/pages/Dashboard.js

@@ -1,7 +1,89 @@

-import React from 'react'; - +import React, {useEffect, useState, useCallback} from 'react'; +import {useStrapi, useAuth} from 'strapi-react-context'; +import Layout from '../layouts/Centered'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Grid from '@material-ui/core/Grid'; +import {makeStyles} from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; +import {useTranslation} from 'react-i18next'; const Dashboard = () => { - return <div>Dashboard – NOT IMPLEMENTED</div>; + const classes = useStyles(); + const {t} = useTranslation(); + const [myEvents, setMyEvents] = useState([]); + const strapi = useStrapi(); + const {authState, token} = useAuth(); + const fetchEvents = useCallback( + async query => { + const myEvents = await strapi.services.events.find(query); + setMyEvents(myEvents); + }, + [strapi.services.events] + ); + useEffect(() => { + if (!token) return; + const { + user: {events = []}, + } = authState; + fetchEvents( + events + .reduce((acc, eventId) => { + return acc + `id_in=${eventId}&`; + }, '') + .substring(-1) + ); + }, [authState, token, fetchEvents]); + + if (!token || !myEvents) return <div>Not connected</div>; + + return ( + <Layout> + <Grid container className={classes.root} spacing={2}> + <Grid item xs={6}> + <Grid container justify="center" spacing={4}> + {myEvents.map(event => ( + <Grid key={event.id} item> + <Card className={classes.card}> + <CardContent> + <Typography gutterBottom variant="h5" component="h2"> + {event.name} + </Typography> + <Typography variant="body1"> + {t('event.fields.starts_on')} + </Typography> + + <Typography variant="body2" gutterBottom> + {event.date || t('event.fields.empty')} + </Typography> + + <Typography variant="body1"> + {t('event.fields.address')} + </Typography> + <Typography variant="body2" gutterBottom> + {event.address || t('event.fields.empty')} + </Typography> + </CardContent> + <CardActions> + <Button href={`/e/${event.id}`}>See event</Button> + </CardActions> + </Card> + </Grid> + ))} + </Grid> + </Grid> + </Grid> + </Layout> + ); }; +const useStyles = makeStyles(theme => ({ + root: { + flexGrow: 1, + }, + card: { + minWidth: '300px', + }, +})); export default Dashboard;
M app/src/pages/Event.jsapp/src/pages/Event.js

@@ -68,14 +68,17 @@ };

const addToMyEvents = () => { if (!event) return; - localStorage.setItem('addToMyEvents', event.id); setIsAddToMyEvent(true); }; + const signUp = () => { if (!event) return; - localStorage.setItem('addToMyEvents', event.id); - history.push('/register'); + history.push({ + pathname: '/register', + state: {event: event.id}, + }); }; + const signIn = history.push.bind(undefined, '/login'); const goToDashboard = history.push.bind(undefined, '/dashboard'); const goProfile = history.push.bind(undefined, '/profile');
M app/src/pages/NotConfirmed.jsapp/src/pages/NotConfirmed.js

@@ -12,7 +12,7 @@ import CardActionArea from '@material-ui/core/CardActions';

import CardActions from '@material-ui/core/CardActions'; import Typography from '@material-ui/core/Typography'; -export default () => { +const NotConfirmed = () => { const {t} = useTranslation(); const {token} = useAuth(); if (token) {

@@ -46,3 +46,5 @@ </Card>

</Layout> ); }; + +export default NotConfirmed;
M app/src/pages/SignIn.jsapp/src/pages/SignIn.js

@@ -3,15 +3,17 @@ import Layout from '../layouts/Centered';

import Card from '@material-ui/core/Card'; import CardMedia from '@material-ui/core/CardMedia'; import Logo from '../components/Logo'; -import SignIn from '../containers/SignIn'; +import SignInContainer from '../containers/SignIn'; -export default () => { +const SignIn = () => { return ( <Layout> <Card> <CardMedia component={Logo} /> - <SignIn /> + <SignInContainer /> </Card> </Layout> ); }; + +export default SignIn;
M app/src/pages/SignUp.jsapp/src/pages/SignUp.js

@@ -3,15 +3,17 @@ import Layout from '../layouts/Centered';

import Card from '@material-ui/core/Card'; import CardMedia from '@material-ui/core/CardMedia'; import Logo from '../components/Logo'; -import SignUp from '../containers/SignUp'; +import Su from '../containers/SignUp'; -export default () => { +const SignUp = () => { return ( <Layout> <Card> <CardMedia component={Logo} /> - <SignUp /> + <Su /> </Card> </Layout> ); }; + +export default SignUp;
M app/src/pages/SignUpSuccess.jsapp/src/pages/SignUpSuccess.js

@@ -8,9 +8,14 @@ import Button from '@material-ui/core/Button';

import CardContent from '@material-ui/core/CardContent'; import CardActions from '@material-ui/core/CardActions'; import Typography from '@material-ui/core/Typography'; - -export default () => { +import {useAuth} from 'strapi-react-context'; +import {Redirect} from 'react-router-dom'; +const SignUpSuccess = () => { const {t} = useTranslation(); + const {token} = useAuth(); + if (!token) { + return <Redirect to="/" />; + } return ( <Layout> <Card>

@@ -48,3 +53,5 @@ </Card>

</Layout> ); }; + +export default SignUpSuccess;
M app/src/setupTests.jsapp/src/setupTests.js

@@ -8,16 +8,11 @@

// FROM https://github.com/akiran/react-slick/blob/master/test-setup.js window.matchMedia = window.matchMedia || - function () { - return { - matches: false, - addListener: function () {}, - removeListener: function () {}, - }; - }; + (() => ({ + matches: false, + addListener: () => {}, + removeListener: () => {}, + })); window.requestAnimationFrame = - window.requestAnimationFrame || - function (callback) { - setTimeout(callback, 0); - }; + window.requestAnimationFrame || (callback => setTimeout(callback, 0));
M extensions/documentation/public/index.htmlextensions/documentation/public/index.html

@@ -33,7 +33,7 @@ <script class="custom-swagger-ui">

window.onload = function() { const ui = SwaggerUIBundle({ url: "https://petstore.swagger.io/v2/swagger.json", - spec: {"openapi":"3.0.0","info":{"version":"1.0.0","title":"Documentation de l'API Caroster","description":"","termsOfService":"YOUR_TERMS_OF_SERVICE_URL","contact":{"name":"Octree","email":"sysadmin@octree.ch","url":"octree.ch"},"license":{"name":"Apache 2.0","url":"https://www.apache.org/licenses/LICENSE-2.0.html"},"x-generation-date":"06/27/2020 6:41:02 PM"},"x-strapi-config":{"path":"/documentation","showGeneratedFiles":true,"generateDefaultResponse":true,"pluginsForWhichToGenerateDoc":[]},"servers":[{"url":"http://localhost:1337","description":"Development server"},{"url":"https://caroster.dev.octr.ee","description":"Test server"},{"url":"https://caroster.io","description":"Production server"}],"externalDocs":{"description":"Find out more","url":"https://strapi.io/documentation/"},"security":[{"bearerAuth":[]}],"paths":{"/cars":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Car"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"post":{"deprecated":false,"description":"Create a new record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCar"}}}}}},"/cars/count":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[]}},"/cars/{id}":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"put":{"deprecated":false,"description":"Update a record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCar"}}}},"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"delete":{"deprecated":false,"description":"Delete a record","responses":{"200":{"description":"deletes a single record based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]}},"/events":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"post":{"deprecated":false,"description":"Create a new record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewEvent"}}}}}},"/events/count":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[]}},"/events/{id}":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"put":{"deprecated":false,"description":"Update a record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewEvent"}}}},"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"delete":{"deprecated":false,"description":"Delete a record","responses":{"200":{"description":"deletes a single record based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]}}},"components":{"schemas":{"Car":{"required":["id","name","seats"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"seats":{"type":"integer"},"meeting":{"type":"string"},"departure":{"type":"datetime"},"phone_number":{"type":"string"},"details":{"type":"string"}}},"NewCar":{"required":["name","seats"],"properties":{"name":{"type":"string"},"seats":{"type":"integer"},"meeting":{"type":"string"},"departure":{"type":"datetime"},"phone_number":{"type":"string"},"details":{"type":"string"}}},"Event":{"required":["id","name","email"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"date":{"type":"string"},"address":{"type":"string"}}},"NewEvent":{"required":["name","email"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"date":{"type":"string"},"address":{"type":"string"}}},"Error":{"required":["code","message"],"properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"tags":[{"name":"Car"},{"name":"Event"}]}, + spec: {"openapi":"3.0.0","info":{"version":"1.0.0","title":"Documentation de l'API Caroster","description":"","termsOfService":"YOUR_TERMS_OF_SERVICE_URL","contact":{"name":"Octree","email":"sysadmin@octree.ch","url":"octree.ch"},"license":{"name":"Apache 2.0","url":"https://www.apache.org/licenses/LICENSE-2.0.html"},"x-generation-date":"07/08/2020 12:13:00 PM"},"x-strapi-config":{"path":"/documentation","showGeneratedFiles":true,"generateDefaultResponse":true,"pluginsForWhichToGenerateDoc":[]},"servers":[{"url":"http://localhost:1337","description":"Development server"},{"url":"https://caroster.dev.octr.ee","description":"Test server"},{"url":"https://caroster.io","description":"Production server"}],"externalDocs":{"description":"Find out more","url":"https://strapi.io/documentation/"},"security":[{"bearerAuth":[]}],"paths":{"/cars":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Car"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"post":{"deprecated":false,"description":"Create a new record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCar"}}}}}},"/cars/count":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[]}},"/cars/{id}":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"put":{"deprecated":false,"description":"Update a record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Car"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCar"}}}},"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"delete":{"deprecated":false,"description":"Delete a record","responses":{"200":{"description":"deletes a single record based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Car"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]}},"/events":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"post":{"deprecated":false,"description":"Create a new record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewEvent"}}}}}},"/events/count":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[]}},"/events/{id}":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"put":{"deprecated":false,"description":"Update a record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewEvent"}}}},"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"delete":{"deprecated":false,"description":"Delete a record","responses":{"200":{"description":"deletes a single record based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Event"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]}},"/pages":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Page"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"post":{"deprecated":false,"description":"Create a new record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewPage"}}}}}},"/pages/count":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"parameters":[]}},"/pages/{id}":{"get":{"deprecated":false,"description":"","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"put":{"deprecated":false,"description":"Update a record","responses":{"200":{"description":"response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewPage"}}}},"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]},"delete":{"deprecated":false,"description":"Delete a record","responses":{"200":{"description":"deletes a single record based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Page"],"parameters":[{"name":"id","in":"path","description":"","deprecated":false,"required":true,"schema":{"type":"string"}}]}},"/settings":{"get":{"deprecated":false,"description":"Find all the settings's records","responses":{"200":{"description":"Retrieve settings document(s)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Settings"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Settings"],"parameters":[{"name":"_limit","in":"query","required":false,"description":"Maximum number of results possible","schema":{"type":"integer"},"deprecated":false},{"name":"_sort","in":"query","required":false,"description":"Sort according to a specific field.","schema":{"type":"string"},"deprecated":false},{"name":"_start","in":"query","required":false,"description":"Skip a specific number of entries (especially useful for pagination)","schema":{"type":"integer"},"deprecated":false},{"name":"=","in":"query","required":false,"description":"Get entries that matches exactly your input","schema":{"type":"string"},"deprecated":false},{"name":"_ne","in":"query","required":false,"description":"Get records that are not equals to something","schema":{"type":"string"},"deprecated":false},{"name":"_lt","in":"query","required":false,"description":"Get record that are lower than a value","schema":{"type":"string"},"deprecated":false},{"name":"_lte","in":"query","required":false,"description":"Get records that are lower than or equal to a value","schema":{"type":"string"},"deprecated":false},{"name":"_gt","in":"query","required":false,"description":"Get records that are greater than a value","schema":{"type":"string"},"deprecated":false},{"name":"_gte","in":"query","required":false,"description":"Get records that are greater than or equal a value","schema":{"type":"string"},"deprecated":false},{"name":"_contains","in":"query","required":false,"description":"Get records that contains a value","schema":{"type":"string"},"deprecated":false},{"name":"_containss","in":"query","required":false,"description":"Get records that contains (case sensitive) a value","schema":{"type":"string"},"deprecated":false},{"name":"_in","in":"query","required":false,"description":"Get records that matches any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false},{"name":"_nin","in":"query","required":false,"description":"Get records that doesn't match any value in the array of values","schema":{"type":"array","items":{"type":"string"}},"deprecated":false}]},"put":{"deprecated":false,"description":"Update a single settings record","responses":{"200":{"description":"Retrieve settings document(s)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Settings"],"requestBody":{"description":"","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewSettings"}}}},"parameters":[]},"delete":{"deprecated":false,"description":"Delete a single settings record","responses":{"200":{"description":"deletes a single settings based on the ID supplied","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"summary":"","tags":["Settings"],"parameters":[]}}},"components":{"schemas":{"Car":{"required":["id","name","seats"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"seats":{"type":"integer"},"meeting":{"type":"string"},"departure":{"type":"datetime"},"phone_number":{"type":"string"},"details":{"type":"string"},"event":{"required":["id","name","email"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"date":{"type":"string"},"address":{"type":"string"},"cars":{"type":"array","items":{"type":"string"}},"position":{"type":"object"},"waiting_list":{"type":"object"}}},"passengers":{"type":"object"}}},"NewCar":{"required":["name","seats"],"properties":{"name":{"type":"string"},"seats":{"type":"integer"},"meeting":{"type":"string"},"departure":{"type":"datetime"},"phone_number":{"type":"string"},"details":{"type":"string"},"event":{"type":"string"},"passengers":{"type":"object"}}},"Event":{"required":["id","name","email"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"date":{"type":"string"},"address":{"type":"string"},"cars":{"type":"array","items":{"required":["id","name","seats"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"seats":{"type":"integer"},"meeting":{"type":"string"},"departure":{"type":"datetime"},"phone_number":{"type":"string"},"details":{"type":"string"},"event":{"type":"string"},"passengers":{"type":"object"}}}},"position":{"type":"object"},"waiting_list":{"type":"object"}}},"NewEvent":{"required":["name","email"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"date":{"type":"string"},"address":{"type":"string"},"cars":{"type":"array","items":{"type":"string"}},"position":{"type":"object"},"waiting_list":{"type":"object"}}},"Page":{"required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"content":{"type":"string"},"type":{"type":"string","enum":["tos"]}}},"NewPage":{"required":["name"],"properties":{"name":{"type":"string"},"content":{"type":"string"},"type":{"type":"string","enum":["tos"]}}},"Settings":{"required":["id"],"properties":{"id":{"type":"string"},"gtm_id":{"type":"string"}}},"NewSettings":{"properties":{"gtm_id":{"type":"string"}}},"Error":{"required":["code","message"],"properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"tags":[{"name":"Car"},{"name":"Event"},{"name":"Page"},{"name":"Settings"}]}, dom_id: '#swagger-ui', docExpansion: "none", deepLinking: true,
A extensions/users-permissions/config/policies/setMe.js

@@ -0,0 +1,6 @@

+// Set authenticated user ID as queried ID +module.exports = async (ctx, next) => { + ctx.params.id = ctx.state.user.id; + console.log('USER ID', ctx.state.user.id); + await next(); +};
A extensions/users-permissions/config/routes.json

@@ -0,0 +1,20 @@

+{ + "routes": [ + { + "method": "PUT", + "path": "/users/me", + "handler": "CarosterUser.update", + + "config": { + "policies": ["plugins::users-permissions.setme"], + "prefix": "", + "description": "Update an existing user", + "tag": { + "plugin": "users-permissions", + "name": "User", + "actionType": "update" + } + } + } + ] +}
A extensions/users-permissions/controllers/CarosterUser.js

@@ -0,0 +1,111 @@

+const _ = require('lodash'); + +module.exports = { + /** + * Update a record. + * + * @return {Object} + */ + update: async ctx => { + console.log('I AM HEREE'); + const advancedConfigs = await strapi + .store({ + environment: '', + type: 'plugin', + name: 'users-permissions', + key: 'advanced', + }) + .get(); + + const {id} = ctx.params; + const { + email, + username, + password, + firstName, + lastName, + events = [], + } = ctx.request.body; + + const user = await strapi.plugins['users-permissions'].services.user.fetch({ + id, + }); + + if (_.has(ctx.request.body, 'email') && !email) { + return ctx.badRequest('email.notNull'); + } + + if (_.has(ctx.request.body, 'firstName') && !firstName) { + return ctx.badRequest('firstName.notNull'); + } + + if (_.has(ctx.request.body, 'lastName') && !lastName) { + return ctx.badRequest('lastName.notNull'); + } + + if (_.has(ctx.request.body, 'username') && !username) { + return ctx.badRequest('username.notNull'); + } + + if ( + _.has(ctx.request.body, 'password') && + !password && + user.provider === 'local' + ) { + return ctx.badRequest('password.notNull'); + } + + if (_.has(ctx.request.body, 'username')) { + const userWithSameUsername = await strapi + .query('user', 'users-permissions') + .findOne({username}); + + if (userWithSameUsername && userWithSameUsername.id != id) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.username.taken', + message: 'username.alreadyTaken.', + field: ['username'], + }) + ); + } + } + + if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) { + const userWithSameEmail = await strapi + .query('user', 'users-permissions') + .findOne({email}); + + if (userWithSameEmail && userWithSameEmail.id != id) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.email.taken', + message: 'Email already taken', + field: ['email'], + }) + ); + } + } + + let updateData = { + ...ctx.request.body, + }; + + if (_.has(ctx.request.body, 'password') && password === user.password) { + delete updateData.password; + } + + if (!_.has(ctx.request.body, 'events')) { + updateData.events = []; + } + + const data = await strapi.plugins['users-permissions'].services.user.edit( + {id}, + updateData + ); + + ctx.send({...data}); + }, +};
M extensions/users-permissions/models/User.settings.jsonextensions/users-permissions/models/User.settings.json

@@ -1,65 +1,73 @@

{ - "connection": "default", - "info": { - "name": "user", - "description": "" + "kind": "collectionType", + "connection": "default", + "collectionName": "users-permissions_user", + "info": { + "name": "user", + "description": "" + }, + "options": { + "timestamps": true + }, + "attributes": { + "username": { + "type": "string", + "minLength": 3, + "unique": true, + "configurable": false, + "required": true }, - "attributes": { - "username": { - "type": "string", - "minLength": 3, - "unique": true, - "configurable": false, - "required": true - }, - "firstName": { - "type": "string", - "minLength": 3, - "configurable": false, - "required": true - }, - "lastName": { - "type": "string", - "minLength": 3, - "configurable": false, - "required": true - }, - "email": { - "type": "email", - "minLength": 6, - "configurable": false, - "required": true - }, - "provider": { - "type": "string", - "configurable": false - }, - "password": { - "type": "password", - "minLength": 6, - "configurable": false, - "private": true - }, - "resetPasswordToken": { - "type": "string", - "configurable": false, - "private": true - }, - "confirmed": { - "type": "boolean", - "default": false, - "configurable": false - }, - "blocked": { - "type": "boolean", - "default": false, - "configurable": false - }, - "role": { - "model": "role", - "via": "users", - "plugin": "users-permissions", - "configurable": false - } + "firstName": { + "type": "string", + "minLength": 3, + "configurable": false, + "required": true + }, + "lastName": { + "type": "string", + "minLength": 3, + "configurable": false, + "required": true + }, + "email": { + "type": "email", + "minLength": 6, + "configurable": false, + "required": true + }, + "provider": { + "type": "string", + "configurable": false + }, + "password": { + "type": "password", + "minLength": 6, + "configurable": false, + "private": true + }, + "resetPasswordToken": { + "type": "string", + "configurable": false, + "private": true + }, + "confirmed": { + "type": "boolean", + "default": false, + "configurable": false + }, + "blocked": { + "type": "boolean", + "default": false, + "configurable": false + }, + "role": { + "model": "role", + "via": "users", + "plugin": "users-permissions", + "configurable": false + }, + "events": { + "type": "json" } - }+ } +}
M package-lock.jsonpackage-lock.json

@@ -2017,7 +2017,7 @@ "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA=="

}, "axios": { "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "resolved": "https://npm-8ee.hidora.com/axios/-/axios-0.19.2.tgz", "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", "requires": { "follow-redirects": "1.5.10"

@@ -7079,7 +7079,7 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="

}, "moment": { "version": "2.27.0", - "resolved": "https://npm-8ee.hidora.com/moment/-/moment-2.27.0.tgz", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" }, "moment-timezone": {

@@ -10476,40 +10476,11 @@ "strapi-utils": "3.0.5"

} }, "strapi-plugin-sendgrid": { - "version": "file:../strapi-plugin-sendgrid", + "version": "0.1.1", + "resolved": "https://npm-8ee.hidora.com/strapi-plugin-sendgrid/-/strapi-plugin-sendgrid-0.1.1.tgz", + "integrity": "sha512-PNy15SKTsHfGqzKVpFIyujIOn+VFPJ+JdCx6jpaK2g5yQbH63Zuvg5qMgoz52zYrt+IkJEhRnwYwzuxQbrRrJA==", "requires": { "axios": "^0.19.2" - }, - "dependencies": { - "axios": { - "version": "0.19.2", - "resolved": "https://npm-8ee.hidora.com/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "requires": { - "follow-redirects": "1.5.10" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://npm-8ee.hidora.com/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://npm-8ee.hidora.com/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://npm-8ee.hidora.com/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } } }, "strapi-plugin-upload": {

@@ -10586,7 +10557,9 @@ "uuid": "^3.1.0"

} }, "strapi-provider-email-sendgrid-template": { - "version": "0.0.2" + "version": "0.0.2", + "resolved": "https://npm-8ee.hidora.com/strapi-provider-email-sendgrid-template/-/strapi-provider-email-sendgrid-template-0.0.2.tgz", + "integrity": "sha512-mocGrZ01gEwJrE1mVXuhqDQs6aVskfzGBA4YQPBS84NH6om9xy29LTKHkRk2VRiUEOKH4YeywrXgLuFvIKYzWQ==" }, "strapi-provider-email-sendmail": { "version": "3.0.5",
M package.jsonpackage.json

@@ -25,7 +25,7 @@ "strapi-plugin-content-manager": "3.0.5",

"strapi-plugin-content-type-builder": "3.0.5", "strapi-plugin-documentation": "^3.0.5", "strapi-plugin-email": "^3.0.5", - "strapi-plugin-sendgrid": "file://../strapi-plugin-sendgrid", + "strapi-plugin-sendgrid": "^0.1.1", "strapi-plugin-upload": "^3.0.5", "strapi-plugin-users-permissions": "3.0.5", "strapi-provider-email-sendgrid-template": "0.0.2",