Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 36571b5cca | |||
| 7ad96db928 | |||
| 5ce9f108cd | |||
| 99bb737647 | |||
| e2ef540aac | |||
| 6e6119ffaf | |||
| 473edf7472 | |||
| 96b08352a0 | |||
| 7a45d19d2b | |||
| c73b08c1aa | |||
| b6e4347abb | |||
| adb9d2ccde | |||
| edd7f705ab | |||
| ea372ba0f2 | |||
| 779b722662 | |||
| 6bb8baf636 | |||
| 083f7b9c16 | |||
| 0eed896aec | |||
| e8ae224414 | |||
| fa3dcd8fd2 | |||
| 2c0c0a2632 | |||
| 501ee57430 | |||
| 0f6ec17fef | |||
| 112541275b | |||
| e08b879691 | |||
| 527351c232 | |||
| 0ed8da11e1 | |||
| f522e4389e | |||
| efb6527b9b | |||
| ba43bcddc7 | |||
| 3523cc95ee | |||
| c0d32cee12 | |||
| 3b6aa331db | |||
| fe7932e5ae | |||
| 05b64ac44c | |||
| 446e13ceba | |||
| 6570e28bbd | |||
| d146da7ab3 | |||
| ae06e730ad | |||
| f386b93dd2 | |||
| cebdf4d1d2 | |||
| e6738a1565 | |||
| ce9b8b6031 | |||
| 00eac45913 | |||
| 89719a8bbc |
@@ -5,7 +5,7 @@
|
||||
Download the example [or clone the repo](https://git.e-declic.net/talents-tube/app.git):
|
||||
|
||||
```bash
|
||||
git clone
|
||||
git clone
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
@@ -27,10 +27,11 @@ https://redux-saga.js.org/docs/basics/ErrorHandling.html
|
||||
is a library that aims to make application side effect asynchronous things like data fetching and impure things like accessing the browser cache
|
||||
|
||||
## Integration
|
||||
### Naming conventions
|
||||
style classes name syntax : Camel case
|
||||
Try to name without too much precision
|
||||
|
||||
### Naming conventions
|
||||
|
||||
style classes name syntax : Camel case
|
||||
Try to name without too much precision
|
||||
|
||||
### Material UI
|
||||
|
||||
@@ -52,16 +53,16 @@ sudo docker exec -it frontnginx.nginx bash
|
||||
nginx -t && nginx -s reload
|
||||
|
||||
## Test
|
||||
|
||||
### Cypress
|
||||
|
||||
[Gmail-tester]
|
||||
https://github.com/levz0r/gmail-tester
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
### Jenkins
|
||||
|
||||
>in case of emergency
|
||||
make docker-restart ENV=dev
|
||||
|
||||
adduser jenkins root
|
||||
|
||||
> in case of emergency
|
||||
> make docker-restart ENV=dev
|
||||
> adduser jenkins root
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {
|
||||
FETCH_ADS_REQUEST,
|
||||
FETCH_ADS_SUCCESS,
|
||||
FETCH_ADS_FAILURE,
|
||||
FETCH_AD_REQUEST,
|
||||
FETCH_AD_SUCCESS,
|
||||
FETCH_AD_FAILURE,
|
||||
FETCH_EMPHASIS_ADS_REQUEST,
|
||||
FETCH_EMPHASIS_ADS_SUCCESS,
|
||||
FETCH_EMPHASIS_ADS_FAILURE,
|
||||
FETCH_JOBS_REQUEST,
|
||||
FETCH_JOBS_SUCCESS,
|
||||
FETCH_JOBS_FAILURE,
|
||||
FETCH_JOB_REQUEST,
|
||||
FETCH_JOB_SUCCESS,
|
||||
FETCH_JOB_FAILURE,
|
||||
FETCH_EMPHASIS_JOBS_REQUEST,
|
||||
FETCH_EMPHASIS_JOBS_SUCCESS,
|
||||
FETCH_EMPHASIS_JOBS_FAILURE,
|
||||
CLEAR_AD,
|
||||
COUNT_AD_VIEW,
|
||||
TOGGLE_PROMOTED_FILTER_ADS
|
||||
@@ -28,52 +28,52 @@ export const togglePromotedFilterRequest = () => ({
|
||||
|
||||
//Ads list
|
||||
|
||||
export const fetchAdsRequest = (payload) => ({
|
||||
type: FETCH_ADS_REQUEST,
|
||||
export const fetchJobsRequest = (payload) => ({
|
||||
type: FETCH_JOBS_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const fetchAdsSuccess = res => ({
|
||||
type: FETCH_ADS_SUCCESS,
|
||||
export const fetchJobsSuccess = res => ({
|
||||
type: FETCH_JOBS_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
export const fetchAdsFailure = res => ({
|
||||
type: FETCH_ADS_FAILURE,
|
||||
export const fetchJobsFailure = res => ({
|
||||
type: FETCH_JOBS_FAILURE,
|
||||
res
|
||||
});
|
||||
|
||||
//Ads list
|
||||
|
||||
export const fetchEmphasisAdsRequest = (payload) => ({
|
||||
type: FETCH_EMPHASIS_ADS_REQUEST,
|
||||
export const fetchEmphasisJobsRequest = (payload) => ({
|
||||
type: FETCH_EMPHASIS_JOBS_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const fetchEmphasisAdsSuccess = res => ({
|
||||
type: FETCH_EMPHASIS_ADS_SUCCESS,
|
||||
export const fetchEmphasisJobsSuccess = res => ({
|
||||
type: FETCH_EMPHASIS_JOBS_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
export const fetchEmphasisAdsFailure = res => ({
|
||||
type: FETCH_EMPHASIS_ADS_FAILURE,
|
||||
export const fetchEmphasisJobsFailure = res => ({
|
||||
type: FETCH_EMPHASIS_JOBS_FAILURE,
|
||||
res
|
||||
});
|
||||
|
||||
//Single ad
|
||||
|
||||
export const fetchAdRequest = payload => ({
|
||||
type: FETCH_AD_REQUEST,
|
||||
export const fetchJobRequest = payload => ({
|
||||
type: FETCH_JOB_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const fetchAdSuccess = res => ({
|
||||
type: FETCH_AD_SUCCESS,
|
||||
export const fetchJobSuccess = res => ({
|
||||
type: FETCH_JOB_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
export const fetchAdFailure = res => ({
|
||||
type: FETCH_AD_FAILURE,
|
||||
export const fetchJobFailure = res => ({
|
||||
type: FETCH_JOB_FAILURE,
|
||||
res
|
||||
});
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import {
|
||||
POST_AD_ANSWER_REQUEST,
|
||||
POST_AD_ANSWER_FAILURE,
|
||||
POST_AD_ANSWER_SUCCESS,
|
||||
FETCH_ADS_ANSWER_REQUEST,
|
||||
FETCH_ADS_ANSWER_SUCCESS,
|
||||
FETCH_ADS_ANSWER_FAILURE,
|
||||
FETCH_JOBS_ANSWER_REQUEST,
|
||||
FETCH_JOBS_ANSWER_SUCCESS,
|
||||
FETCH_JOBS_ANSWER_FAILURE,
|
||||
FETCH_ANSWER_REQUEST,
|
||||
FETCH_ANSWER_SUCCESS,
|
||||
FETCH_ANSWER_FAILURE,
|
||||
@@ -47,19 +47,19 @@ export const postMessageAnswerSuccess = res => ({
|
||||
});
|
||||
|
||||
|
||||
export const fetchAdsAnsweredRequest = payload => ({
|
||||
type: FETCH_ADS_ANSWER_REQUEST,
|
||||
export const fetchJobsAnsweredRequest = payload => ({
|
||||
type: FETCH_JOBS_ANSWER_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const fetchAdsAnsweredSuccess = res => ({
|
||||
type: FETCH_ADS_ANSWER_SUCCESS,
|
||||
export const fetchJobsAnsweredSuccess = res => ({
|
||||
type: FETCH_JOBS_ANSWER_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
|
||||
export const fetchAdsAnsweredFailure = errors => ({
|
||||
type: FETCH_ADS_ANSWER_FAILURE,
|
||||
export const fetchJobsAnsweredFailure = errors => ({
|
||||
type: FETCH_JOBS_ANSWER_FAILURE,
|
||||
errors
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import {
|
||||
UPLOAD_MEDIA_REQUEST,
|
||||
UPLOAD_MEDIA_FAILURE,
|
||||
UPLOAD_MEDIA_SUCCESS
|
||||
UPLOAD_MEDIA_SUCCESS,
|
||||
UPLOAD_MEDIA_PRES_REQUEST,
|
||||
UPLOAD_MEDIA_PRES_FAILURE,
|
||||
UPLOAD_MEDIA_PRES_SUCCESS,
|
||||
UPLOAD_MEDIA_CV_REQUEST,
|
||||
UPLOAD_MEDIA_CV_FAILURE,
|
||||
UPLOAD_MEDIA_CV_SUCCESS,
|
||||
|
||||
} from "../types";
|
||||
|
||||
export const uploadMedia = payload => ({
|
||||
@@ -18,6 +25,35 @@ import {
|
||||
type: UPLOAD_MEDIA_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
export const uploadMediaPres = payload => ({
|
||||
type: UPLOAD_MEDIA_PRES_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const uploadMediaPresFailure = errors => ({
|
||||
type: UPLOAD_MEDIA_PRES_FAILURE,
|
||||
errors
|
||||
});
|
||||
|
||||
|
||||
export const uploadMediaPresSuccess = res => ({
|
||||
type: UPLOAD_MEDIA_PRES_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
export const uploadMediaCv = payload => ({
|
||||
type: UPLOAD_MEDIA_CV_REQUEST,
|
||||
payload
|
||||
});
|
||||
|
||||
export const uploadMediaCvFailure = errors => ({
|
||||
type: UPLOAD_MEDIA_CV_FAILURE,
|
||||
errors
|
||||
});
|
||||
|
||||
export const uploadMediaCvSuccess = res => ({
|
||||
type: UPLOAD_MEDIA_CV_SUCCESS,
|
||||
res
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import AssignmentIcon from '@material-ui/icons/Assignment';
|
||||
import RoomIcon from '@material-ui/icons/Room';
|
||||
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
||||
import BusinessCenterIcon from '@material-ui/icons/BusinessCenter';
|
||||
import Business from '@material-ui/icons/Business';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
const variantIcon = {
|
||||
@@ -13,6 +14,7 @@ const variantIcon = {
|
||||
room: RoomIcon,
|
||||
location_on: LocationOnIcon,
|
||||
business_center: BusinessCenterIcon,
|
||||
business: Business,
|
||||
};
|
||||
|
||||
const styles = theme => ({
|
||||
|
||||
@@ -6,12 +6,14 @@ import RoomIcon from '@material-ui/icons/Room';
|
||||
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
||||
import BusinessCenterIcon from '@material-ui/icons/BusinessCenter';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Business from '@material-ui/icons/Business';
|
||||
|
||||
const variantIcon = {
|
||||
assignment: AssignmentIcon,
|
||||
room: RoomIcon,
|
||||
location_on: LocationOnIcon,
|
||||
business_center: BusinessCenterIcon,
|
||||
business: Business,
|
||||
};
|
||||
|
||||
const styles = theme => ({
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
import { JobPostingJsonLd } from 'next-seo';
|
||||
|
||||
const JobPosting = props => {
|
||||
return (
|
||||
|
||||
<JobPostingJsonLd
|
||||
datePosted="2020-01-06T03:37:40Z"
|
||||
description={props.job_description}
|
||||
hiringOrganization={{
|
||||
name: props.job_brand,
|
||||
sameAs: props.job_brand_link,
|
||||
}}
|
||||
jobLocation={{
|
||||
addressLocality: props.job_location,
|
||||
|
||||
}}
|
||||
title={props.job_title}
|
||||
validThrough="2020-01-06"
|
||||
applicantLocationRequirements="FR"
|
||||
/>
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
JobPosting.propTypes = {
|
||||
// seo_title: PropTypes.string.isRequired,
|
||||
// seo_description: PropTypes.string.isRequired,
|
||||
// seo_url: PropTypes.string.isRequired,
|
||||
// image: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default JobPosting
|
||||
@@ -6,8 +6,9 @@ const OgHead = props => {
|
||||
return (
|
||||
<Head>
|
||||
<title key="title">{props.seo_title}</title>
|
||||
<meta name="description" key="description" content={props.seo_description} />
|
||||
|
||||
<meta name="robots" content="noindex, nofollow"></meta>
|
||||
<meta name="description" kenoindexy="description" content={props.seo_description} />
|
||||
<meta name="keywords" content={props.seo_key}/>
|
||||
<meta key="og:url" property="og:url" content={props.seo_url} />
|
||||
<meta key="og:type" property="og:type" content="article" />
|
||||
<meta key="og:title" property="og:title" content={props.seo_title} />
|
||||
@@ -16,10 +17,20 @@ const OgHead = props => {
|
||||
property="og:description"
|
||||
content={props.seo_description}
|
||||
/>
|
||||
<meta name="keywords" content={props.seo_key}/>
|
||||
<meta key="og:image" property="og:image" content={props.image} />
|
||||
|
||||
<link rel="canonical" href={"https://www.application.bzh/" + props.seo_url} />
|
||||
<meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:site" content="@TalentsTube"/>
|
||||
<meta name="twitter:title" content={props.seo_title}/>
|
||||
<meta name="twitter:description" content={props.seo_title}/>
|
||||
<meta name="twitter:image" content={props.image}/>
|
||||
<meta http-equiv='cache-control' content='no-store,no-cache'></meta>
|
||||
<meta http-equiv='expires' content='0'></meta>
|
||||
<meta http-equiv='pragma' content='no-cache'></meta>
|
||||
<link rel="canonical" href={ props.seo_url} />
|
||||
|
||||
</Head>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,32 @@ const useStyles = makeStyles(theme => ({
|
||||
height: '100%',
|
||||
},
|
||||
},
|
||||
},
|
||||
videoPresentation: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
position: 'relative',
|
||||
paddingBottom: '56%', /* 16:9 58%*/
|
||||
'& iframe': {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 'calc(50% - 50vw)',
|
||||
width: '100vw',
|
||||
height: '100%',
|
||||
},
|
||||
[theme.breakpoints.up('md')]: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
position: 'relative',
|
||||
paddingBottom: '56.5%', /* 16:9 */
|
||||
'& iframe': {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 'calc(50% - 32vw)',
|
||||
width: '64vw',
|
||||
height: '100%',
|
||||
},
|
||||
},
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -37,14 +63,20 @@ export default function VideoVimeo(props) {
|
||||
|
||||
const {videoId, title, options, classesOverride, autoplay} = props;
|
||||
const classes = useStyles();
|
||||
|
||||
let className = classes.video;
|
||||
if (classesOverride) {
|
||||
className = classes.videoPresentation;
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={classes.video +' '+classesOverride}>
|
||||
|
||||
<section className={className +' '+classesOverride}>
|
||||
<iframe className='player'
|
||||
src={"https://player.vimeo.com/video/"+ videoId + options+"?autoplay="+autoplay}
|
||||
frameBorder="0"
|
||||
title={title}
|
||||
webkitallowfullscreen="true" mozallowfullscreen="true" allowFullScreen></iframe>
|
||||
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,14 +2,13 @@ import React, { Component, Fragment } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from "react-redux";
|
||||
import { subscribeUserToPushRequest } from '../../actions/user'
|
||||
import getConfig from 'next/config'
|
||||
|
||||
|
||||
import { urlB64ToUint8Array, payloadFromSubscription } from './Utility'
|
||||
|
||||
var swRegistration = null
|
||||
|
||||
//TODO: put in config
|
||||
const applicationServerPublicKey = 'BNFyiyPiLH97Dgc0m1vXluUNaCN6y3Hkgd4YcqS2lVkP8my3tq2D5gM5g7cY6R4VxC7GljSzkLRu+k+oO+2TtjU=';
|
||||
|
||||
const WebPushContext = React.createContext()
|
||||
|
||||
function WebPushConsumer(props) {
|
||||
@@ -26,6 +25,8 @@ function WebPushConsumer(props) {
|
||||
</WebPushContext.Consumer>
|
||||
)
|
||||
}
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
class WebPush extends Component {
|
||||
static Consumer = WebPushConsumer;
|
||||
|
||||
@@ -91,7 +92,7 @@ class WebPush extends Component {
|
||||
if (isSubscribed) {
|
||||
this.onUpdateSubscriptionOnServer(subscription)
|
||||
} else {
|
||||
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey)
|
||||
const applicationServerKey = urlB64ToUint8Array(publicRuntimeConfig.applicationServerPublicKey)
|
||||
swRegistration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: applicationServerKey
|
||||
|
||||
@@ -0,0 +1,497 @@
|
||||
import React, { useState, Component, Fragment } from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import { Alert, AlertTitle } from '@material-ui/lab';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import { connect } from 'react-redux'
|
||||
import { updateUserRequest } from '../../actions/user'
|
||||
import getConfig from 'next/config'
|
||||
import Validator from "validator";
|
||||
import AccountProfile from '../organisms/AccountProfile';
|
||||
import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';
|
||||
import {
|
||||
Button,
|
||||
} from '@material-ui/core';
|
||||
|
||||
const styles = theme => ({
|
||||
container: {
|
||||
width: '85%',
|
||||
},
|
||||
form: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: '24px',
|
||||
paddingBottom: theme.spacing(8),
|
||||
marginBottom: theme.spacing(8),
|
||||
'&>div': {
|
||||
marginTop: theme.spacing(1.5),
|
||||
marginBottom: theme.spacing(1.5),
|
||||
}
|
||||
|
||||
},
|
||||
textField: {
|
||||
width: '85%',
|
||||
'&:disabled': {
|
||||
color: theme.palette.secondary.dark,
|
||||
},
|
||||
'& label': {
|
||||
color: theme.palette.primary.dark,
|
||||
},
|
||||
'& fieldset:hover': {
|
||||
borderColor: theme.palette.primary.main + ' !important',
|
||||
},
|
||||
},
|
||||
textFieldSmall: {
|
||||
width: '48%',
|
||||
'&:disabled': {
|
||||
color: theme.palette.secondary.dark,
|
||||
},
|
||||
'& label': {
|
||||
color: theme.palette.primary.dark,
|
||||
},
|
||||
'& fieldset:hover': {
|
||||
borderColor: theme.palette.primary.main + ' !important',
|
||||
},
|
||||
padding: '5px',
|
||||
},
|
||||
});
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
//https://xd.adobe.com/view/ba98331a-9145-4d67-7e27-25a36e519ef4-cca9/screen/a96779d7-bdb3-410a-8f19-e6987acb98ee/Candidature-Step-3
|
||||
class AccountEtape1 extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// This binding is necessary to make `this` work in the callback
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleClose = this.handleClose.bind(this);
|
||||
this.onBlur = this.onBlur.bind(this)
|
||||
this.onSubmit = this.onSubmit.bind(this);
|
||||
}
|
||||
|
||||
state = {
|
||||
file: null,
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
email:'',
|
||||
phone: '',
|
||||
currentJob: '',
|
||||
address1:'',
|
||||
address2 : '',
|
||||
zipCode : '',
|
||||
city : '',
|
||||
country : '',
|
||||
linkedin: '',
|
||||
twitter: '',
|
||||
website: '',
|
||||
mediaId: null,
|
||||
companyId: null,
|
||||
|
||||
};
|
||||
|
||||
handleChange = (e) => {
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
|
||||
//console.log(this.refs.myTextField.input.value);
|
||||
//this.soumettre(e);
|
||||
|
||||
}
|
||||
|
||||
handleClose = (e, reason) => {
|
||||
|
||||
if (reason === 'clickaway') {
|
||||
return;
|
||||
}
|
||||
|
||||
//setOpen(false);
|
||||
};
|
||||
|
||||
onBlur(e) {
|
||||
console.log("blur")
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
console.log("phone=>"+this.state.phone);
|
||||
this.soumettre();
|
||||
}
|
||||
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
this.setState({
|
||||
firstname: nextProps.user.firstname,
|
||||
lastname: nextProps.user.lastname,
|
||||
phone: nextProps.user.phone,
|
||||
email: nextProps.user.email,
|
||||
currentJob: nextProps.user.currentJob,
|
||||
address1 : nextProps.user.address1,
|
||||
address2 : nextProps.user.address2,
|
||||
zipCode : nextProps.user.zipCode,
|
||||
city : nextProps.user.city,
|
||||
country : nextProps.user.country,
|
||||
linkedin: nextProps.user.linkedin,
|
||||
twitter: nextProps.user.twitter,
|
||||
website: nextProps.user.website,
|
||||
companyId: nextProps.companyId,
|
||||
errors: !!!nextProps.errors ? { errors: { message: "" } } : nextProps.errors,
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
firstname: this.props.user.firstname,
|
||||
lastname: this.props.user.lastname,
|
||||
phone: this.props.user.phone,
|
||||
email: this.props.user.email,
|
||||
address1: this.props.user.address1,
|
||||
address2 : this.props.user.address2,
|
||||
zipCode : this.props.user.zipCode,
|
||||
city : this.props.user.city,
|
||||
country : this.props.user.country,
|
||||
currentJob: this.props.user.currentJob,
|
||||
linkedin: this.props.user.linkedin,
|
||||
twitter: this.props.user.twitter,
|
||||
website: this.props.user.website,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
onSubmit = (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
this.soumettre(e);
|
||||
|
||||
}
|
||||
soumettre(e){
|
||||
|
||||
const errors = this.validate(this.state);
|
||||
const success = {};
|
||||
this.setState({ errors });
|
||||
if (!this.state.errors || !this.state.errors.message){
|
||||
|
||||
success.message ="Profil mis à jour";
|
||||
this.setState({ success });
|
||||
const data = new FormData()
|
||||
data.append('firstname', this.state.firstname)
|
||||
data.append('lastname', this.state.lastname)
|
||||
data.append('phone', this.state.phone)
|
||||
//data.append('email', this.state.email)
|
||||
data.append('currentJob', this.state.currentJob)
|
||||
data.append('address1', this.state.address1)
|
||||
data.append('address2', this.state.address2)
|
||||
data.append('zipCode', this.state.zipCode)
|
||||
data.append('city', this.state.city)
|
||||
data.append('country', this.state.country)
|
||||
data.append('linkedin', this.state.linkedin)
|
||||
data.append('twitter', this.state.twitter)
|
||||
data.append('website', this.state.website)
|
||||
|
||||
//TODO:maybe add this two in a single transactionnal saga
|
||||
this.props.updateUserRequest(data)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
validate = data => {
|
||||
const errors = {};
|
||||
errors.message ="";
|
||||
//if (!Validator.isEmail(data.currentJob)) errors.message += "Le poste actuel doit etre un email\n";
|
||||
if (!data.firstname || data.firstname==="") errors.message += "Veuillez saisir votre prénom<br />";
|
||||
if (!data.lastname || data.lastname==="") errors.message += " Veuillez saisir saisir votre nom<br />";
|
||||
if (data.phone=="") errors.message += "Veuillez saisir un numéro de téléphone<br />";
|
||||
if (!data.currentJob || data.currentJob=="") errors.message += "Veuillez saisir votre intitulé de poste actuel ou poste recherché<br />";
|
||||
if ((data.zipCode && data.zipCode!="") && !Validator.isPostalCode(data.zipCode, "FR")) errors.message += "Le code postal n'est pas correct<br />";
|
||||
// if ((data.website && data.website!="") && !Validator.isURL(data.website)) errors.message += " Veuillez ajouter un site internet avec une url valide<br />";
|
||||
// if (!Validator.isMobilePhone(data.phone, "fr-FR") && !Validator.isNumeric(data.phone, "fr-FR")) errors.message += "Le téléphone n'est pas correct<br />";
|
||||
//console.log(errors.email);
|
||||
|
||||
return errors;
|
||||
};
|
||||
AfficherErreurs() {
|
||||
if (!this.state.errors || !this.state.errors.message){
|
||||
return "";
|
||||
}else if (this.state.errors.length != 0 && this.state.errors.message!="") {
|
||||
return (
|
||||
<Alert severity="error">
|
||||
{ ReactHtmlParser(this.state.errors.message)}
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
AfficherSuccess() {
|
||||
// if (this.state.success && this.state.success.length != 0 && this.state.success.message != "") {
|
||||
// return (
|
||||
// <Snackbar open={open} autoHideDuration={1000} onClose={() => this.setState({open: false})}>
|
||||
// <Alert onClose={() => this.setState({open: false})} severity="success">
|
||||
// {ReactHtmlParser(this.state.success.message)}
|
||||
// </Alert>
|
||||
// </Snackbar>
|
||||
|
||||
|
||||
// );
|
||||
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
inputFilesystemChange = (e) => {
|
||||
|
||||
console.log("inputFilesystemChange");
|
||||
var file = e.target.files[0]
|
||||
this.setState({ picture: file })
|
||||
|
||||
const data = new FormData()
|
||||
data.append('file', file)
|
||||
this.props.updateUserPictureRequest(data)
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { classes, user } = this.props
|
||||
const logoUrl = user.picture;
|
||||
function refresh() {
|
||||
document
|
||||
.location
|
||||
.reload(true);
|
||||
|
||||
}
|
||||
return (
|
||||
<section className={classes.container}>
|
||||
<form className={classes.form}
|
||||
autoComplete="off" focused="true" name="monForm" ref="formToSubmit">
|
||||
{/* {!!logoUrl && <Avatar className={classes.logo}
|
||||
classes={{ img: classes.MuiAvatarImg }}
|
||||
src={publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.postedContentUrl + logoUrl} alt="candidatLogo" />} */}
|
||||
|
||||
{/* {!!user.pictureLoading && <Loader />}
|
||||
{!!!user.pictureLoading && !!!logoUrl &&
|
||||
(<Fragment><input
|
||||
type="file" accept="image/*" capture="filesystem"
|
||||
className={classes.input}
|
||||
style={{ display: 'none' }}
|
||||
id="raised-button-file"
|
||||
multiple
|
||||
type="file"
|
||||
onChange={this.inputFilesystemChange}
|
||||
/>
|
||||
<label htmlFor="raised-button-file">
|
||||
<Button component="span" className={classes.importButton} classes={{ root: classes.rootButton }}>
|
||||
<img alt="talents-tube" src='/static/images/default/account-avatar-default.svg'
|
||||
className={classes.iconButton} />
|
||||
<Typography align="left" className={classes.textButton}>
|
||||
J'<span className={classes.underlined}>importe</span> ma photo de profil
|
||||
</Typography>
|
||||
<KeyboardArrowRightIcon className={classes.InputKeyboardArrowRightIcon} />
|
||||
</Button>
|
||||
</label></Fragment>)
|
||||
} */}
|
||||
{this.AfficherErreurs()}
|
||||
{this.AfficherSuccess()}
|
||||
|
||||
|
||||
<TextField
|
||||
name="firstname"
|
||||
required
|
||||
id="outlined-required"
|
||||
label="Prénom"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.firstname}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="lastname"
|
||||
required
|
||||
id="outlined-required"
|
||||
label="Nom"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.lastname}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
disabled
|
||||
name="email"
|
||||
id="outlined"
|
||||
label="E-mail"
|
||||
required
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.email}
|
||||
onChange={this.handleChange}
|
||||
type="mail"
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="phone"
|
||||
id="outlined"
|
||||
label="Téléphone"
|
||||
required
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.phone ? this.state.phone: ''}
|
||||
onChange={this.handleChange}
|
||||
type="tel"
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<TextField
|
||||
name="currentJob"
|
||||
id="outlined"
|
||||
label="Poste actuel"
|
||||
required
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.currentJob && this.state.currentJob !='null' ? this.state.currentJob : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="address1"
|
||||
id="outlined"
|
||||
label="Adresse"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.address1 && this.state.address1 !='null' ? this.state.address1 : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="address2"
|
||||
id="outlined"
|
||||
label="Adresse complémentaire"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
value={this.state.address2 && this.state.address2 !='null' ? this.state.address2 : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
<div className={classes.container}>
|
||||
<TextField
|
||||
name="zipCode"
|
||||
id="outlined"
|
||||
label="Code postal"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.textFieldSmall }}
|
||||
variant="outlined"
|
||||
value={this.state.zipCode && this.state.zipCode !='null' ? this.state.zipCode : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="city"
|
||||
id="outlined"
|
||||
label="Ville"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.textFieldSmall }}
|
||||
variant="outlined"
|
||||
value={this.state.city && this.state.city !='null' ? this.state.city : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="country"
|
||||
id="outlined"
|
||||
label="Pays"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.textFieldSmall }}
|
||||
variant="outlined"
|
||||
value={this.state.country && this.state.country !='null' ? this.state.country : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<TextField
|
||||
name="linkedin"
|
||||
id="outlined"
|
||||
label="Linkedin"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
placeholder="http://www.linkedin.com/in/"
|
||||
value={this.state.linkedin && this.state.linkedin !='null' ? this.state.linkedin : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="twitter"
|
||||
id="outlined"
|
||||
label="Twitter"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
placeholder="http://twitter.com/.."
|
||||
value={this.state.twitter && this.state.twitter !='null' ? this.state.twitter : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
name="website"
|
||||
id="outlined"
|
||||
label="Site internet"
|
||||
className={classes.textField}
|
||||
classes={{ root: classes.rootTextfield }}
|
||||
variant="outlined"
|
||||
placeholder="http://monsite.fr"
|
||||
value={this.state.website && this.state.website !='null' ? this.state.website : ''}
|
||||
onChange={this.handleChange}
|
||||
onBlur={this.onBlur}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={refresh}
|
||||
className={classes.button}>
|
||||
Enregistrer
|
||||
</Button>
|
||||
</form>
|
||||
{/* <div id="F" className={classes.foot}>
|
||||
<Button variant="contained" className={classes.button + ' cypButtonSendApplication'} onClick={this.onSubmit}>Mettre à jour!</Button>
|
||||
</div> */}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
user: state.user ,
|
||||
loading: !!state.user.loading,
|
||||
pictureLoading: !!state.user.pictureLoading,
|
||||
errors: state.user.errors || ownProps.errors,
|
||||
mediaId: state.media.message && state.media.message.mediaId,
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, { updateUserRequest })(AccountEtape1));
|
||||
@@ -0,0 +1,317 @@
|
||||
import React, {Fragment} from 'react'
|
||||
import {connect} from "react-redux";
|
||||
import {makeStyles} from '@material-ui/styles';
|
||||
import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight';
|
||||
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||
import {Button, Typography} from '@material-ui/core';
|
||||
import dynamic from 'next/dynamic'
|
||||
import {withStyles} from '@material-ui/core/styles'
|
||||
import {uploadMediaPres} from '../../actions/media'
|
||||
import {errorMessageSelector} from '../../reducers/media'
|
||||
import {fetchCompanyRequest} from '../../actions/companies'
|
||||
import {fetchCurrentUserRequest} from '../../actions/user'
|
||||
import VideoVimeo from '../atoms/VideoVimeo'
|
||||
import Router from 'next/router'
|
||||
import Loader from '../templates/loader'
|
||||
import Ar from "lodash/array"
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import { Alert, AlertTitle } from '@material-ui/lab';
|
||||
import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Container from '@material-ui/core/Container';
|
||||
import Hidden from '@material-ui/core/Hidden';
|
||||
|
||||
const styles = theme => ({
|
||||
container: {
|
||||
width: '100%',
|
||||
},
|
||||
root: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
margin: theme.spacing(1),
|
||||
flexWrap: 'wrap',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
|
||||
recorderContainer: {
|
||||
//display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%'
|
||||
},
|
||||
rootButton: {
|
||||
textTransform: 'inherit'
|
||||
},
|
||||
underlined: {
|
||||
textDecoration: 'underline'
|
||||
},
|
||||
textButton: {
|
||||
fontWeight: '700',
|
||||
fontSize: '1.15em',
|
||||
paddingLeft: theme.spacing(2)
|
||||
},
|
||||
videoPresentation: {
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
},
|
||||
conseilButton: {
|
||||
color: "#ffffff",
|
||||
backgroundColor: "#25D89A",
|
||||
padding: theme.spacing(3, 2),
|
||||
margin: theme.spacing(1),
|
||||
width: "100%",
|
||||
textAlign: "right",
|
||||
boxShadow: '0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1' +
|
||||
'px rgba(0, 0, 0, 0.14)',
|
||||
'&:hover': {
|
||||
color: "#ffffff",
|
||||
backgroundColor: "#25D89A",
|
||||
}
|
||||
},
|
||||
importButton: {
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
padding: theme.spacing(3, 2),
|
||||
margin: theme.spacing(1),
|
||||
width: "100%",
|
||||
textAlign: "right",
|
||||
boxShadow: '0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1' +
|
||||
'px rgba(0, 0, 0, 0.14)',
|
||||
'&:hover': {
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
}
|
||||
},
|
||||
InputKeyboardArrowDownIconBlank: {
|
||||
fontSize: '2.5em',
|
||||
color: "#ffffff",
|
||||
textAlign: "right"
|
||||
},
|
||||
InputKeyboardArrowDownIcon: {
|
||||
fontSize: '2.5em',
|
||||
color: "#1689FB",
|
||||
textAlign: "right"
|
||||
}
|
||||
});
|
||||
const Recorder = dynamic(() => import ('../organisms/Recorder'), {ssr: false})
|
||||
class Etape2 extends React.Component {
|
||||
state = {
|
||||
loading: true,
|
||||
activeStep: 0,
|
||||
data: {},
|
||||
openSnack: false,
|
||||
errors: {},
|
||||
success : {}
|
||||
};
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
localStorage.setItem('loginRedirect', window.location)
|
||||
|
||||
if (!!!localStorage.getItem('ttJWT')) {
|
||||
Router.push("/Login")
|
||||
} else
|
||||
this.setState({loading: false, firstname: this.props.user.firstname, videoPres: this.props.user.videoPres, video: this.props.user.presentation_video_id})
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
|
||||
this.setState({
|
||||
loading: nextProps.loading,
|
||||
openSnack: !!!_.isEmpty(nextProps.errors),
|
||||
errors: !!!nextProps.errors
|
||||
? {
|
||||
errors: {
|
||||
message: ""
|
||||
}
|
||||
}
|
||||
: nextProps.errors,
|
||||
videoPres: nextProps.videoPres,
|
||||
video: nextProps.video
|
||||
})
|
||||
//window.location.reload(false);
|
||||
if (nextProps.media.status === 'success') {
|
||||
const success = {};
|
||||
success.message ="Vidéo mis à jour";
|
||||
this.setState({ success });
|
||||
this.setActiveStep(1);
|
||||
}
|
||||
}
|
||||
|
||||
setActiveStep = (step) => {
|
||||
this.setState({activeStep: step})
|
||||
}
|
||||
|
||||
inputFilesystemChange = (e) => {
|
||||
this.uploadMediaPres(e)
|
||||
}
|
||||
|
||||
inputCamRecorderChange = (e) => {
|
||||
this.uploadMediaPres(e)
|
||||
}
|
||||
|
||||
uploadMediaPres = (e) => {
|
||||
var file = e.target.files[0]
|
||||
|
||||
const data = new FormData()
|
||||
data.append('upload', file)
|
||||
//this.setState({ videoPres: videoPres })
|
||||
|
||||
this
|
||||
.props
|
||||
.uploadMediaPres(data)
|
||||
}
|
||||
|
||||
AfficherSuccess() {
|
||||
if (!this.state.success || !this.state.success.message) {
|
||||
|
||||
} else if (this.state.success.length != 0 && this.state.success.message != "") {
|
||||
return (
|
||||
<Snackbar open={open} autoHideDuration={1000} onClose={() => this.setState({open: false})}>
|
||||
<Alert onClose={() => this.setState({open: false})} severity="success">
|
||||
{ReactHtmlParser(this.state.success.message)}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
handleClose = (event, reason) => {
|
||||
this.setState({openSnack: false});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {classes, company} = this.props;
|
||||
const {loading, activeStep} = this.state;
|
||||
let video;
|
||||
if (this.state.videoPres) {
|
||||
video = <VideoVimeo videoId={Ar.last(_.split(this.state.videoPres, '/'))} autoplay='1' classesOverride="videoPresentation"/>;
|
||||
} else {
|
||||
video = "";
|
||||
}
|
||||
return (
|
||||
<section className={classes.container}>
|
||||
<Fragment>
|
||||
{this.AfficherSuccess()}
|
||||
{ loading ? <Loader/> : <div></div> }
|
||||
|
||||
<div className={classes.root}>
|
||||
<Hidden xsUp>
|
||||
|
||||
</Hidden>
|
||||
<Container maxWidth="md">
|
||||
|
||||
<Grid container
|
||||
justify="center"
|
||||
alignItems="center"
|
||||
spacing={2}>
|
||||
<Grid item xs={12} sm={12} md={12} lg={6} lg={6}>
|
||||
<div className={classes.recorderContainer}>
|
||||
<Recorder uploader={this.props.uploadMediaPres} titreBouton="Remplacer ma vidéo"/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={12} md={12} lg={6} xl={6}>
|
||||
<div>
|
||||
<label htmlFor="import-conseil">
|
||||
<Button
|
||||
component="span"
|
||||
className={classes.conseilButton}
|
||||
classes={{
|
||||
root: classes.rootButton}}
|
||||
onClick={() => Router.push(`/Conseils`)}>
|
||||
<img
|
||||
alt="talents-tube"
|
||||
src='/statique/images/conseils-talentstube.svg'
|
||||
className={classes.iconButton}/>
|
||||
<Typography align="left" className={classes.textButton}>
|
||||
<span className={classes.underlined}>Comment</span> créer ma vidéo
|
||||
</Typography>
|
||||
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIconBlank}/>
|
||||
</Button>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
accept="video/*"
|
||||
className={classes.input + ' cypButtonImportVid'}
|
||||
style={{display: 'none'}}
|
||||
id="import-button-file"
|
||||
onChange={this.inputFilesystemChange}/>
|
||||
<label htmlFor="import-button-file">
|
||||
<Button
|
||||
component="span"
|
||||
className={classes.importButton}
|
||||
classes={{
|
||||
root: classes.rootButton}}>
|
||||
<img
|
||||
alt="talents-tube"
|
||||
src='/statique/images/Import.svg'
|
||||
className={classes.iconButton}/>
|
||||
<Typography align="left" className={classes.textButton}>
|
||||
J'<span className={classes.underlined}>importe</span> ma vidéo de réponse
|
||||
|
||||
</Typography>
|
||||
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIcon}/>
|
||||
</Button>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</Grid>
|
||||
<Hidden xsUp>
|
||||
|
||||
</Hidden>
|
||||
|
||||
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
|
||||
<div className={classes.videoPresentation}>
|
||||
{video}
|
||||
</div>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Container>
|
||||
</div>
|
||||
{/* <div className={classes.textContainer}>
|
||||
|
||||
</div> */}
|
||||
|
||||
</Fragment>
|
||||
</section>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Etape2.getInitialProps = function (context) {
|
||||
|
||||
const {companyId} = context.query
|
||||
const {res} = context
|
||||
//TODO :really needed ?
|
||||
context
|
||||
.store
|
||||
.dispatch(fetchCurrentUserRequest())
|
||||
|
||||
if (!!companyId)
|
||||
context.store.dispatch(fetchCompanyRequest(companyId))
|
||||
|
||||
return {}; //leave this please
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
|
||||
return {
|
||||
loading: !!state.media.loading,
|
||||
media: state.media,
|
||||
offre: state.ad,
|
||||
//errors: errorMessageSelector(state),
|
||||
user: state.user,
|
||||
company: state.company
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, {fetchCurrentUserRequest, fetchCompanyRequest, uploadMediaPres})(Etape2));
|
||||
@@ -0,0 +1,257 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { connect } from "react-redux";
|
||||
import { fetchCurrentUserRequest } from '../../actions/user'
|
||||
import { fetchCompanyRequest } from '../../actions/companies'
|
||||
import { uploadMediaCv } from '../../actions/media'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { Button, Typography, Divider, Hidden } from '@material-ui/core';
|
||||
import KeyboardArrowRightIcon from '@material-ui/icons/KeyboardArrowRight';
|
||||
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||
import Loader from '../../components/templates/loader'
|
||||
import Snack from '../../components/atoms/snack';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import { Alert, AlertTitle } from '@material-ui/lab';
|
||||
import ReactHtmlParser from 'react-html-parser';
|
||||
import getConfig from 'next/config'
|
||||
import Card from '@material-ui/core/Card';
|
||||
import CardActions from '@material-ui/core/CardActions';
|
||||
import CardContent from '@material-ui/core/CardContent';
|
||||
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
margin: theme.spacing(1),
|
||||
},
|
||||
rootButton: {
|
||||
textTransform: 'inherit',
|
||||
},
|
||||
underlined: {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
textButton: {
|
||||
fontWeight: '700',
|
||||
fontSize: '1.15em',
|
||||
paddingLeft: theme.spacing(2),
|
||||
},
|
||||
InputKeyboardArrowDownIcon: {
|
||||
fontSize: '2.5em',
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
importButton: {
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
padding: theme.spacing(3, 2),
|
||||
margin: theme.spacing(1),
|
||||
width: "370px",
|
||||
boxShadow: '0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1' +
|
||||
'px rgba(0, 0, 0, 0.14)',
|
||||
'&:hover': {
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
class Etape3 extends React.Component {
|
||||
state = {
|
||||
loading: true,
|
||||
openSnack: false,
|
||||
cv:false,
|
||||
errors: {},
|
||||
success : {}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
localStorage.setItem('loginRedirect', window.location)
|
||||
|
||||
if(!!!localStorage.getItem('ttJWT'))
|
||||
{
|
||||
Router.push("/Login")
|
||||
}
|
||||
else
|
||||
this.setState({
|
||||
loading: false,
|
||||
cvLink: this.props.user.cv
|
||||
})
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
|
||||
this.setState({
|
||||
cvLink: nextProps.cvLink,
|
||||
loading: nextProps.loading,
|
||||
openSnack: !!!_.isEmpty(nextProps.errors),
|
||||
errors: !!!nextProps.errors ? { errors: { message: "" } } : nextProps.errors,
|
||||
})
|
||||
this.state.cvLink = nextProps.cvLink;
|
||||
if (nextProps.loading) {
|
||||
const success = {};
|
||||
success.message ="CV mis à jour";
|
||||
console.log("CV mis à jour!!!")
|
||||
if(this.state.cvLink) console.log(this.state.cvLink)
|
||||
this.setState({ success });
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
inputFilesystemChange = (e) => {
|
||||
this.uploadMediaCv(e)
|
||||
}
|
||||
|
||||
uploadMediaCv = (e) => {
|
||||
var file = e.target.files[0]
|
||||
|
||||
const data = new FormData()
|
||||
data.append('upload', file)
|
||||
|
||||
this.props.uploadMediaCv(data)
|
||||
}
|
||||
|
||||
AfficherSuccess() {
|
||||
if (!this.state.success || !this.state.success.message) {
|
||||
console.log("Erreur Upload CV");
|
||||
return "";
|
||||
} else if (this.state.success.length != 0 && this.state.success.message != "") {
|
||||
return (
|
||||
<Snackbar open={open} autoHideDuration={1000} onClose={() => this.setState({open: false})}>
|
||||
<Alert onClose={() => this.setState({open: false})} severity="success">
|
||||
{ReactHtmlParser(this.state.success.message)}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
AfficherLienCv() {
|
||||
console.log("afficher lien");
|
||||
if (this.state.cvLink !="") {
|
||||
|
||||
return (
|
||||
|
||||
<Fragment>
|
||||
<Hidden> </Hidden>
|
||||
<Hidden> </Hidden>
|
||||
|
||||
<Hidden> </Hidden>
|
||||
<Hidden> </Hidden>
|
||||
<Card variant="" style={{
|
||||
width:370+"px",
|
||||
boxShadow: '0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1' +
|
||||
'px rgba(0, 0, 0, 0.14)',
|
||||
marginLeft : '10px',
|
||||
marginTop:'10px'
|
||||
|
||||
}}>
|
||||
<Hidden> </Hidden>
|
||||
<CardActions>
|
||||
<Button size="small">MON CV</Button>
|
||||
</CardActions>
|
||||
<CardContent>
|
||||
<Typography >
|
||||
<a href={publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.postedContentCv + this.state.cvLink}
|
||||
target="_blank"
|
||||
style={{
|
||||
color:'#1689FB',
|
||||
'&:hover': {
|
||||
color: '#1689FB',
|
||||
},
|
||||
fontWeight: '700',
|
||||
fontSize: '1em',
|
||||
}}
|
||||
>
|
||||
Visionner mon CV
|
||||
</a>
|
||||
<br />
|
||||
{/* <a href="https://www.permatheque.fr/PDF/mansobufukuoka-larevolutiondunseulbrindepaille.pdf" target="_blank">lien</a> */}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
|
||||
</Card>
|
||||
</Fragment>
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, company } = this.props;
|
||||
const { loading } = this.state;
|
||||
return (
|
||||
<Fragment>
|
||||
{ loading ?
|
||||
<Loader /> :
|
||||
<Fragment>
|
||||
{this.AfficherSuccess()}
|
||||
|
||||
<input
|
||||
type="file"
|
||||
accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document, .pdf, .odt"
|
||||
className={classes.input+' cypButtonImportVid'}
|
||||
style={{ display: 'none' }}
|
||||
id="import-button-file"
|
||||
onChange={this.inputFilesystemChange}
|
||||
/>
|
||||
<label htmlFor="import-button-file">
|
||||
<Button component="span" className={classes.importButton} classes={{ root: classes.rootButton }}>
|
||||
<img alt="talents-tube" src='/statique/images/Import-cv-candidat.svg' className={classes.iconButton} />
|
||||
<Typography className={classes.textButton}>
|
||||
J'<span className={classes.underlined}>importe</span> mon CV
|
||||
</Typography>
|
||||
<KeyboardArrowDownIcon className={ classes. InputKeyboardArrowDownIcon }/>
|
||||
</Button>
|
||||
|
||||
</label>
|
||||
<Hidden> </Hidden>
|
||||
{this.AfficherLienCv()}
|
||||
|
||||
</Fragment>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Etape3.getInitialProps = function (context) {
|
||||
|
||||
const { adId, companyId } = context.query
|
||||
const {res} = context
|
||||
//TODO :really needed ?
|
||||
context.store.dispatch(fetchCurrentUserRequest())
|
||||
|
||||
if(!!adId)
|
||||
context.store.dispatch(fetchJobRequest(adId))
|
||||
else if(!!companyId)
|
||||
context.store.dispatch(fetchCompanyRequest(companyId))
|
||||
|
||||
return {};//leave this please
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
// console.log("mapStateToProps")
|
||||
// console.log(state.loading)
|
||||
// console.log(state.user)
|
||||
// console.log(state.media.message)
|
||||
return {
|
||||
user: state.user ,
|
||||
cvLink : state.media.message,
|
||||
loading: !!state.media.loading,
|
||||
cv : true,
|
||||
//errors: errorMessageSelector(state),
|
||||
user: state.user,
|
||||
company: state.company
|
||||
};
|
||||
}
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchCurrentUserRequest, fetchCompanyRequest, uploadMediaCv })(Etape3));
|
||||
@@ -0,0 +1,485 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import clsx from 'clsx';
|
||||
// import AccountStep from "../../components/organisms/AccountStep";
|
||||
import AccountEtape1 from '../organisms/AccountEtape1';
|
||||
import AccountEtape2 from '../organisms/AccountEtape2';
|
||||
import AccountEtape3 from '../organisms/AccountEtape3';
|
||||
import {withStyles} from '@material-ui/core/styles';
|
||||
// import Switch from '@material-ui/core/Switch';
|
||||
import PhoneIcon from '@material-ui/icons/Phone';
|
||||
import MailIcon from '@material-ui/icons/Mail';
|
||||
import PublicIcon from '@material-ui/icons/Public';
|
||||
import DuoIcon from '@material-ui/icons/Duo';
|
||||
import LinkedInIcon from '@material-ui/icons/LinkedIn';
|
||||
import Facebook from '@material-ui/icons/Facebook';
|
||||
// import FormGroup from '@material-ui/core/FormGroup'; import FormControlLabel
|
||||
// from '@material-ui/core/FormControlLabel'; import FormControl from
|
||||
// '@material-ui/core/FormControl';
|
||||
import {updateUserRequest, updateUserPictureRequest} from '../../actions/user'
|
||||
import {makeStyles} from '@material-ui/styles';
|
||||
import {connect} from 'react-redux'
|
||||
import getConfig from 'next/config'
|
||||
import BottomNavigation from '@material-ui/core/BottomNavigation';
|
||||
// import BottomNavigationAction from
|
||||
// '@material-ui/core/BottomNavigationAction';
|
||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||
// import FavoriteIcon from '@material-ui/icons/Favorite'; import LocationOnIcon
|
||||
// from '@material-ui/icons/LocationOn';
|
||||
|
||||
import Box from '@material-ui/core/Box';
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardActions,
|
||||
CardContent,
|
||||
Avatar,
|
||||
Typography,
|
||||
Divider,
|
||||
Button,
|
||||
LinearProgress,
|
||||
Stepper,
|
||||
Step,
|
||||
StepLabel,
|
||||
StepContent,
|
||||
StepButton,
|
||||
Paper,
|
||||
Grid
|
||||
} from '@material-ui/core';
|
||||
|
||||
const styles = theme => ({
|
||||
container: {
|
||||
width: '100%'
|
||||
},
|
||||
button: {
|
||||
textTransform: 'inherit',
|
||||
marginLeft: theme.spacing(8),
|
||||
marginRight: theme.spacing(8),
|
||||
padding: theme.spacing(1.2, 2),
|
||||
color: theme.palette.secondary.main,
|
||||
backgroundColor: theme.palette.primary.important
|
||||
},
|
||||
stickToBottom: {
|
||||
width: '100%',
|
||||
position: 'fixed',
|
||||
bottom: 0
|
||||
}
|
||||
});
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {},
|
||||
details: {
|
||||
display: 'flex'
|
||||
},
|
||||
avatar: {
|
||||
marginLeft: 'auto',
|
||||
height: 110,
|
||||
width: 100,
|
||||
flexShrink: 0,
|
||||
flexGrow: 0
|
||||
},
|
||||
progress: {
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
information: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
[
|
||||
theme
|
||||
.breakpoints
|
||||
.up('md')
|
||||
]: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-around',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
padding: theme.spacing(7, 7)
|
||||
},
|
||||
'& a': {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
},
|
||||
texteBlanc: {
|
||||
color: "#fff"
|
||||
},
|
||||
uploadButton: {
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginRight: theme.spacing(1)
|
||||
},
|
||||
actionsContainer: {
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
resetContainer: {
|
||||
padding: theme.spacing(3)
|
||||
}
|
||||
}));
|
||||
|
||||
function getSteps() {
|
||||
return ['Informations personnelles', 'Vidéo de présentation', 'Expériences professionnelles'];
|
||||
}
|
||||
|
||||
function getStepContent(step) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return <AccountEtape1 ></AccountEtape1>;
|
||||
case 1:
|
||||
return <AccountEtape2></AccountEtape2>;
|
||||
case 2:
|
||||
return <AccountEtape3></AccountEtape3>;
|
||||
default:
|
||||
return 'Unknown step';
|
||||
}
|
||||
}
|
||||
|
||||
const AccountProfile = props => {
|
||||
const {
|
||||
className,
|
||||
user,
|
||||
...rest
|
||||
} = props;
|
||||
const logoUrl = user.picture;
|
||||
const classes = useStyles();
|
||||
|
||||
// const user = { name: 'Laurent Laniau', city: 'Questembert', country:
|
||||
// 'France', timezone: '', avatar: '/images/avatars/avatar_11.png' };
|
||||
const {publicRuntimeConfig} = getConfig()
|
||||
const [activeStep,
|
||||
setActiveStep] = React.useState(0);
|
||||
const [completed,
|
||||
setCompleted] = React.useState(new Set());
|
||||
const [skipped,
|
||||
setSkipped] = React.useState(new Set());
|
||||
const [state,
|
||||
setState] = React.useState({checkedA: true, checkedB: true});
|
||||
const steps = getSteps();
|
||||
|
||||
const totalSteps = () => {
|
||||
return getSteps().length;
|
||||
};
|
||||
|
||||
const isStepOptional = (step) => {
|
||||
return step === 4;
|
||||
};
|
||||
|
||||
const handleSkip = () => {
|
||||
if (!isStepOptional(activeStep)) {
|
||||
// You probably want to guard against something like this it should never occur
|
||||
// unless someone's actively trying to break something.
|
||||
throw new Error("You can't skip a step that isn't optional.");
|
||||
}
|
||||
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
setSkipped((prevSkipped) => {
|
||||
const newSkipped = new Set(prevSkipped.values());
|
||||
newSkipped.add(activeStep);
|
||||
return newSkipped;
|
||||
});
|
||||
};
|
||||
|
||||
const skippedSteps = () => {
|
||||
return skipped.size;
|
||||
};
|
||||
|
||||
const completedSteps = () => {
|
||||
return completed.size;
|
||||
};
|
||||
|
||||
const allStepsCompleted = () => {
|
||||
return completedSteps() === totalSteps() - skippedSteps();
|
||||
};
|
||||
|
||||
const isLastStep = () => {
|
||||
return activeStep === totalSteps() - 1;
|
||||
};
|
||||
|
||||
const handleNext = () => {
|
||||
const newActiveStep = isLastStep() && !allStepsCompleted()
|
||||
? // It's the last step, but not all steps have been completed
|
||||
// find the first step that has been completed
|
||||
steps.findIndex((step, i) => !completed.has(i))
|
||||
: activeStep + 1;
|
||||
|
||||
setActiveStep(newActiveStep);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleStep = (step) => () => {
|
||||
console.log("step");
|
||||
console.log(step);
|
||||
setActiveStep(step);
|
||||
};
|
||||
|
||||
const handleComplete = () => {
|
||||
const newCompleted = new Set(completed);
|
||||
newCompleted.add(activeStep);
|
||||
setCompleted(newCompleted);
|
||||
|
||||
/**
|
||||
* Sigh... it would be much nicer to replace the following if conditional with
|
||||
* `if (!this.allStepsComplete())` however state is not set when we do this,
|
||||
* thus we have to resort to not being very DRY.
|
||||
*/
|
||||
if (completed.size !== totalSteps() - skippedSteps()) {
|
||||
handleNext();
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setActiveStep(0);
|
||||
setCompleted(new Set());
|
||||
setSkipped(new Set());
|
||||
};
|
||||
|
||||
const isStepSkipped = (step) => {
|
||||
return skipped.has(step);
|
||||
};
|
||||
|
||||
const handleChange = (event) => {
|
||||
setState({
|
||||
...state,
|
||||
[event.target.name]: event.target.checked
|
||||
});
|
||||
};
|
||||
|
||||
function isStepComplete(step) {
|
||||
return completed.has(step);
|
||||
}
|
||||
function refresh() {
|
||||
document
|
||||
.location
|
||||
.reload(true);
|
||||
console.log("refresh")
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
spacing={4}
|
||||
direction="row"
|
||||
justify="space-between"
|
||||
alignItems="flex-start">
|
||||
<Grid item lg={3} md={6} xl={4} xs={12}>
|
||||
<Card {...rest} className={clsx(classes.root, className)}>
|
||||
<CardContent>
|
||||
<div id="fb-root"></div>
|
||||
<script
|
||||
async
|
||||
defer
|
||||
crossorigin="anonymous"
|
||||
src="https://connect.facebook.net/fr_FR/sdk.js#xfbml=1&version=v8.0&appId=2332071840142634&autoLogAppEvents=1"
|
||||
nonce="O28M4TTm"></script>
|
||||
<div className={classes.details}>
|
||||
<div>
|
||||
<Typography gutterBottom variant="h5">
|
||||
{user.lastname}
|
||||
{user.firstname}
|
||||
<a href="#" onClick={refresh}><RefreshIcon className={classes.menuButton}/></a>
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.locationText}
|
||||
color="textSecondary"
|
||||
variant="body1">
|
||||
<MailIcon className={classes.menuButton}/>
|
||||
: {user.email}<br/>
|
||||
<PhoneIcon className={classes.menuButton}/>
|
||||
: {user.phone}<br/>
|
||||
<LinkedInIcon className={classes.menuButton}/>
|
||||
: {(user.linkedin && user.linkedin != '' && user.linkedin != 'null')
|
||||
? <a href={user.linkedin} target="_blank">Lien sur mon linkendIn</a>
|
||||
: 'Non renseigné'}<br/>
|
||||
<PublicIcon className={classes.menuButton}/>
|
||||
: {(user.website && user.website != '' && user.website != 'null')
|
||||
? <a href={user.website} target="_blank">Lien sur mon site</a>
|
||||
: 'Non renseigné'}<br/>
|
||||
|
||||
|
||||
|
||||
</Typography>
|
||||
|
||||
</div>
|
||||
{/* <Avatar
|
||||
className={classes.avatar}
|
||||
src={publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.postedContentUrl + logoUrl}/> */}
|
||||
</div>
|
||||
<div>
|
||||
<Box m={3}/>
|
||||
<Divider/>
|
||||
<Box m={3}/>
|
||||
<Typography
|
||||
className={classes.locationText}
|
||||
color="textSecondary"
|
||||
variant="body1">
|
||||
|
||||
<DuoIcon className={classes.menuButton}/>
|
||||
: {(user.alias && user.alias != '' && user.alias != 'null')
|
||||
? <a
|
||||
href={publicRuntimeConfig.cvThequeUrl + "talent/" + user.alias}
|
||||
target="_blank">Voir mon profil TalentsTube
|
||||
</a>
|
||||
: 'Non renseigné'}<br/>
|
||||
<div
|
||||
class="fb-share-button"
|
||||
data-href={publicRuntimeConfig.cvThequeUrl + "talent/" + user.alias}
|
||||
data-layout="button_count"
|
||||
data-size="small">
|
||||
|
||||
<Facebook className={classes.menuButton}/>
|
||||
:
|
||||
<a
|
||||
target="_blank"
|
||||
href={"https://www.facebook.com/sharer/sharer.php?u=" + publicRuntimeConfig.cvThequeUrl + "talent/" + user.alias + "%2F&src=sdkpreparse"}
|
||||
class="fb-xfbml-parse-ignore"> Partager mon profil
|
||||
</a>
|
||||
</div>
|
||||
</Typography>
|
||||
</div>
|
||||
{/* <div className={classes.progress}>
|
||||
<Typography variant="body1">Etat du Profil: 70%</Typography>
|
||||
<LinearProgress value={70} variant="determinate"/>
|
||||
</div> */}
|
||||
|
||||
</CardContent>
|
||||
<Box m={2}/>
|
||||
<Divider/>
|
||||
<Box m={2}/>
|
||||
<div className={classes.information}>
|
||||
<Typography className={classes.texteBlanc} align="left"></Typography>
|
||||
</div>
|
||||
{/* <CardActions>
|
||||
<Button className={classes.uploadButton} color="primary" variant="text">
|
||||
Remplacer une photo de profil
|
||||
</Button>
|
||||
<Button variant="text">Supprimer photo de profil</Button>
|
||||
</CardActions> */}
|
||||
<Box m={1}/>
|
||||
<Divider/>
|
||||
{/* <CardContent>
|
||||
<Typography variant="body1"></Typography>
|
||||
<FormControlLabel
|
||||
value="end"
|
||||
control={< Switch checked = {
|
||||
state.checkedA
|
||||
}
|
||||
onChange = {
|
||||
handleChange
|
||||
}
|
||||
name = "checkedA" color = "primary" />}
|
||||
label="Je souhaite afficher mon profil sur la CV Vidéothèque Talents Tube"
|
||||
labelPlacement="start"/>
|
||||
|
||||
</CardContent> */}
|
||||
|
||||
|
||||
|
||||
<CardActions>
|
||||
|
||||
<Stepper nonLinear activeStep={activeStep} orientation="vertical">
|
||||
{steps.map((label, index) => {
|
||||
const stepProps = {};
|
||||
const buttonProps = {};
|
||||
if (isStepOptional(index)) {
|
||||
buttonProps.optional = <Typography variant="caption">Optional</Typography>;
|
||||
}
|
||||
if (isStepSkipped(index)) {
|
||||
stepProps.completed = false;
|
||||
}
|
||||
return (
|
||||
<Step key={label} className={classes.actionsContainer} {...stepProps}>
|
||||
<StepButton
|
||||
onClick={handleStep(index)}
|
||||
completed={isStepComplete(index)}
|
||||
{...buttonProps}>
|
||||
{label}
|
||||
</StepButton>
|
||||
|
||||
</Step>
|
||||
);
|
||||
})}
|
||||
</Stepper>
|
||||
</CardActions>
|
||||
<Divider/>
|
||||
|
||||
<div>
|
||||
|
||||
<div>
|
||||
|
||||
<div>
|
||||
|
||||
{/* {isStepOptional(activeStep) && !completed.has(activeStep) && (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleSkip}
|
||||
className={classes.button}
|
||||
>
|
||||
Skip
|
||||
</Button>
|
||||
)} */}
|
||||
|
||||
{/* {activeStep !== steps.length &&
|
||||
(completed.has(activeStep) ? (
|
||||
<Typography variant="caption" className={classes.completed}>
|
||||
Step {activeStep + 1} already completed
|
||||
</Typography>
|
||||
) : (
|
||||
<Button variant="contained" color="primary" onClick={handleComplete}>
|
||||
{completedSteps() === totalSteps() - 1 ? 'Finish' : 'Complete Step'}
|
||||
</Button>
|
||||
))} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<Box m={2}/>
|
||||
<CardContent>
|
||||
<BottomNavigation className={classes.stickToBottom}>
|
||||
<Button
|
||||
disabled={activeStep === 0}
|
||||
onClick={handleBack}
|
||||
className={classes.button}>
|
||||
Etape précédente
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleNext}
|
||||
className={classes.button}>
|
||||
Etape suivante
|
||||
</Button>
|
||||
{/* <BottomNavigationAction label="Recents" icon={< RestoreIcon />}/>
|
||||
<BottomNavigationAction label="Favorites" icon={< FavoriteIcon />}/>
|
||||
<BottomNavigationAction label="Nearby" icon={< LocationOnIcon />}/> */}
|
||||
</BottomNavigation>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
</Grid>
|
||||
<Grid item lg={9} md={6} xl={8} xs={12}>
|
||||
{getStepContent(activeStep)}
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
AccountProfile.propTypes = {
|
||||
className: PropTypes.string
|
||||
};
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
user: state.user,
|
||||
loading: !!state.user.loading,
|
||||
errors: state.user.errors || ownProps.errors
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, {updateUserRequest})(AccountProfile))
|
||||
@@ -0,0 +1,218 @@
|
||||
import React, {Fragment} from 'react';
|
||||
import {Hidden} from '@material-ui/core';
|
||||
import PropTypes from 'prop-types';
|
||||
import clsx from 'clsx';
|
||||
// import AccountStep from "../../components/organisms/AccountStep";
|
||||
import AccountEtape1 from './AccountEtape1';
|
||||
import AccountEtape2 from './AccountEtape2';
|
||||
import AccountEtape3 from './AccountEtape3';
|
||||
import {withStyles} from '@material-ui/core/styles';
|
||||
// import Switch from '@material-ui/core/Switch';
|
||||
import PhoneIcon from '@material-ui/icons/Phone';
|
||||
import MailIcon from '@material-ui/icons/Mail';
|
||||
import PublicIcon from '@material-ui/icons/Public';
|
||||
import DuoIcon from '@material-ui/icons/Duo';
|
||||
import LinkedInIcon from '@material-ui/icons/LinkedIn';
|
||||
import Facebook from '@material-ui/icons/Facebook';
|
||||
// import FormGroup from '@material-ui/core/FormGroup'; import FormControlLabel
|
||||
// from '@material-ui/core/FormControlLabel'; import FormControl from
|
||||
// '@material-ui/core/FormControl';
|
||||
import {updateUserRequest, updateUserPictureRequest} from '../../actions/user'
|
||||
import {makeStyles} from '@material-ui/styles';
|
||||
import {connect} from 'react-redux'
|
||||
import getConfig from 'next/config'
|
||||
import Router from 'next/router'
|
||||
|
||||
import BottomNavigation from '@material-ui/core/BottomNavigation';
|
||||
// import BottomNavigationAction from
|
||||
// '@material-ui/core/BottomNavigationAction';
|
||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||
// import FavoriteIcon from '@material-ui/icons/Favorite'; import LocationOnIcon
|
||||
// from '@material-ui/icons/LocationOn';
|
||||
|
||||
import Box from '@material-ui/core/Box';
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardActions,
|
||||
CardContent,
|
||||
Avatar,
|
||||
Typography,
|
||||
Divider,
|
||||
Button,
|
||||
LinearProgress,
|
||||
Stepper,
|
||||
Step,
|
||||
StepLabel,
|
||||
StepContent,
|
||||
StepButton,
|
||||
Paper,
|
||||
Grid
|
||||
} from '@material-ui/core';
|
||||
|
||||
const styles = theme => ({
|
||||
container: {
|
||||
width: '100%'
|
||||
},
|
||||
button: {
|
||||
textTransform: 'inherit',
|
||||
marginLeft: theme.spacing(8),
|
||||
marginRight: theme.spacing(8),
|
||||
padding: theme.spacing(1.2, 2),
|
||||
color: theme.palette.secondary.main,
|
||||
backgroundColor: theme.palette.primary.important
|
||||
},
|
||||
stickToBottom: {
|
||||
width: '100%',
|
||||
position: 'fixed',
|
||||
bottom: 0
|
||||
}
|
||||
});
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {},
|
||||
details: {
|
||||
display: 'flex'
|
||||
},
|
||||
avatar: {
|
||||
marginLeft: 'auto',
|
||||
height: 110,
|
||||
width: 100,
|
||||
flexShrink: 0,
|
||||
flexGrow: 0
|
||||
},
|
||||
progress: {
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
information: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
[
|
||||
theme
|
||||
.breakpoints
|
||||
.up('md')
|
||||
]: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-around',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
padding: theme.spacing(7, 7)
|
||||
},
|
||||
'& a': {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
},
|
||||
texteBlanc: {
|
||||
color: "#fff"
|
||||
},
|
||||
uploadButton: {
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginRight: theme.spacing(1)
|
||||
},
|
||||
actionsContainer: {
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
resetContainer: {
|
||||
padding: theme.spacing(3)
|
||||
}
|
||||
}));
|
||||
|
||||
const AccountProfile = props => {
|
||||
const {
|
||||
className,
|
||||
user,
|
||||
...rest
|
||||
} = props;
|
||||
const logoUrl = user.picture;
|
||||
const classes = useStyles();
|
||||
|
||||
// const user = { name: 'Laurent Laniau', city: 'Questembert', country:
|
||||
// 'France', timezone: '', avatar: '/images/avatars/avatar_11.png' };
|
||||
const {publicRuntimeConfig} = getConfig()
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
spacing={4}
|
||||
direction="row"
|
||||
justify="space-between"
|
||||
alignItems="flex-start">
|
||||
|
||||
<Grid item lg={9} md={6} xl={8} xs={12}>
|
||||
<Fragment>
|
||||
<Hidden> </Hidden>
|
||||
<Hidden> </Hidden>
|
||||
|
||||
<Card
|
||||
variant="outlined"
|
||||
style={{
|
||||
width: 420 + "px",
|
||||
textAlign:"center"
|
||||
}}>
|
||||
<CardActions></CardActions>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
Tu n'as pas tout dit dans ta vidéo?<br/>
|
||||
Pour mettre toutes les chances de ton côté,
|
||||
<b> dépose ton CV old school (format pdf, word)!</b>
|
||||
</Typography>
|
||||
</CardContent>
|
||||
|
||||
</Card>
|
||||
<Hidden> </Hidden>
|
||||
<Card
|
||||
variant="outlined"
|
||||
style={{
|
||||
width: 420 + "px",
|
||||
textAlign:"center"
|
||||
}}>
|
||||
<CardContent>
|
||||
<AccountEtape3></AccountEtape3>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Hidden> </Hidden>
|
||||
<Hidden> </Hidden>
|
||||
<Card
|
||||
variant="outlined"
|
||||
style={{
|
||||
width: 420 + "px",
|
||||
textAlign:"center"
|
||||
}}>
|
||||
<CardContent>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => Router.push(`/Candidatures`)}
|
||||
className={classes.button}>
|
||||
Voir mes candidatures
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Fragment>
|
||||
|
||||
</Grid>
|
||||
<Grid item lg={3} md={6} xl={4} xs={12}></Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
AccountProfile.propTypes = {
|
||||
className: PropTypes.string
|
||||
};
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
user: state.user,
|
||||
loading: !!state.user.loading,
|
||||
errors: state.user.errors || ownProps.errors
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, {updateUserRequest})(AccountProfile))
|
||||
@@ -0,0 +1,147 @@
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Stepper from '@material-ui/core/Stepper';
|
||||
import Step from '@material-ui/core/Step';
|
||||
import StepButton from '@material-ui/core/StepButton';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import AccountEtape1 from '../organisms/AccountEtape1';
|
||||
import AccountEtape2 from '../organisms/AccountEtape2';
|
||||
import AccountEtape3 from '../organisms/AccountEtape3';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
width: '100%',
|
||||
},
|
||||
button: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
completed: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
instructions: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
function getSteps() {
|
||||
return ['Informations personnelles', 'Vidéo de présentation', 'Expériences professionnelles'];
|
||||
}
|
||||
|
||||
function getStepContent(step) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return <AccountEtape1 ></AccountEtape1>;
|
||||
case 1:
|
||||
return <AccountEtape2></AccountEtape2>;
|
||||
case 2:
|
||||
return <AccountEtape3></AccountEtape3>;
|
||||
default:
|
||||
return 'Unknown step';
|
||||
}
|
||||
}
|
||||
|
||||
export default function HorizontalNonLinearStepper() {
|
||||
const classes = useStyles();
|
||||
const [activeStep, setActiveStep] = React.useState(0);
|
||||
const [completed, setCompleted] = React.useState({});
|
||||
const steps = getSteps();
|
||||
|
||||
const totalSteps = () => {
|
||||
return steps.length;
|
||||
};
|
||||
|
||||
const completedSteps = () => {
|
||||
return Object.keys(completed).length;
|
||||
};
|
||||
|
||||
const isLastStep = () => {
|
||||
return activeStep === totalSteps() - 1;
|
||||
};
|
||||
|
||||
const allStepsCompleted = () => {
|
||||
return completedSteps() === totalSteps();
|
||||
};
|
||||
|
||||
const handleNext = () => {
|
||||
const newActiveStep =
|
||||
isLastStep() && !allStepsCompleted()
|
||||
? // It's the last step, but not all steps have been completed,
|
||||
// find the first step that has been completed
|
||||
steps.findIndex((step, i) => !(i in completed))
|
||||
: activeStep + 1;
|
||||
setActiveStep(newActiveStep);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleStep = (step) => () => {
|
||||
setActiveStep(step);
|
||||
};
|
||||
|
||||
const handleComplete = () => {
|
||||
const newCompleted = completed;
|
||||
newCompleted[activeStep] = true;
|
||||
setCompleted(newCompleted);
|
||||
handleNext();
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setActiveStep(0);
|
||||
setCompleted({});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Stepper alternativeLabel nonLinear activeStep={activeStep}>
|
||||
{steps.map((label, index) => (
|
||||
<Step key={label}>
|
||||
<StepButton onClick={handleStep(index)} completed={completed[index]}>
|
||||
{label}
|
||||
</StepButton>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
<div>
|
||||
{allStepsCompleted() ? (
|
||||
<div>
|
||||
{/* <Typography className={classes.instructions}>
|
||||
Toutes les étapes sont terminées -
|
||||
</Typography>
|
||||
<Button onClick={handleReset}>Annuler</Button> */}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography>
|
||||
<div>
|
||||
{/* <Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
|
||||
Précédent
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleNext}
|
||||
className={classes.button}
|
||||
>
|
||||
Suivant
|
||||
</Button> */}
|
||||
{/* {activeStep !== steps.length &&
|
||||
(completed[activeStep] ? (
|
||||
<Typography variant="caption" className={classes.completed}>
|
||||
Step {activeStep + 1} already completed
|
||||
</Typography>
|
||||
) : (
|
||||
<Button variant="contained" color="primary" onClick={handleComplete}>
|
||||
{completedSteps() === totalSteps() - 1 ? 'Etape valide' : 'Processus terminé'}
|
||||
</Button>
|
||||
))} */}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import PropTypes from 'prop-types';
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import Link from 'next/link';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardContent,
|
||||
CardActions,
|
||||
Divider,
|
||||
Grid,
|
||||
Button,
|
||||
TextField
|
||||
} from '@material-ui/core';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {}
|
||||
}));
|
||||
|
||||
const AccountVideoPres = props => {
|
||||
const { className, ...rest } = props;
|
||||
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Card
|
||||
{...rest}
|
||||
className={clsx(classes.root, className)}
|
||||
>
|
||||
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
AccountVideoPres.propTypes = {
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
export default AccountVideoPres;
|
||||
@@ -151,7 +151,7 @@ class CompanyRowComponent extends React.Component {
|
||||
const nbOffre = (rowData.count_ads > 0) ? offre : 'Candidature spontanée';
|
||||
|
||||
return (
|
||||
<Link href={`/Entreprise/${rowData.id}-${_.kebabCase(rowData.brand_name)}-${_.kebabCase(rowData.addresses.billing.city)}`} >
|
||||
<Link href={`/Entreprise/${rowData.id}-${_.kebabCase(rowData.brand_name)}`} >
|
||||
<Card className={classes.card + ' cypCardCompany'}>
|
||||
<CardContent className={classes.content}>
|
||||
<CardMedia
|
||||
|
||||
@@ -20,6 +20,8 @@ import WorkOutlineIcon from '@material-ui/icons/WorkOutline';
|
||||
import AccountCircleOutlinedIcon from '@material-ui/icons/AccountCircleOutlined';
|
||||
import FolderSharedIcon from '@material-ui/icons/FolderShared';
|
||||
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
|
||||
import PermContactCalendar from '@material-ui/icons/PermContactCalendar';
|
||||
import VideoCam from '@material-ui/icons/Videocam';
|
||||
import SettingsIcon from '@material-ui/icons/Settings';
|
||||
import PowerSettingsNewIcon from '@material-ui/icons/PowerSettingsNew';
|
||||
import ArrowForward from '@material-ui/icons/ArrowForward';
|
||||
@@ -37,6 +39,7 @@ import { withRouter } from "next/router";
|
||||
import ActiveLink from "./../atoms/Activelink";
|
||||
import axios from 'axios';
|
||||
import setAuthorizationHeader from "../../data/setAuthorizationHeader";
|
||||
import getConfig from 'next/config'
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
@@ -327,7 +330,7 @@ class Header extends React.Component {
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
|
||||
return (
|
||||
@@ -344,7 +347,7 @@ class Header extends React.Component {
|
||||
|
||||
<Link href="/" >
|
||||
<a className={classes.darkMenuItem}><ListItem classes={{ root: classes.rootListItem }}>
|
||||
<img alt="talents-tube" src='/static/images/logos/TalentsTube_logo-color.svg' className={classes.menuLogo} />
|
||||
<img alt="talents-tube" src='/statique/images/logos/TalentsTube_logo-color.svg' className={classes.menuLogo} />
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
|
||||
@@ -381,18 +384,9 @@ class Header extends React.Component {
|
||||
</ListItem></a>
|
||||
</ActiveLink>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className={classes.videothequeLinkGroup}>
|
||||
<a href="https://www.talentstube.com/faire-offre-emploi-video" className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<VideoIcon className={classes.icon} />
|
||||
<ListItemText classes={{ primary: classes.ListItemText }} primary='CV vidéothèque'>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
</a>
|
||||
</div>
|
||||
<div className={classes.blogLinkGroup}>
|
||||
<a href="https://blog.talentstube.com" className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<a href={publicRuntimeConfig.blogUrl} className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<NotesIcon className={classes.icon} />
|
||||
<ListItemText classes={{ primary: classes.ListItemText }} primary='Blog'>
|
||||
</ListItemText>
|
||||
@@ -400,7 +394,7 @@ class Header extends React.Component {
|
||||
</a>
|
||||
</div>
|
||||
<div className={classes.recruteurLinkGroup}>
|
||||
<a href="https://www.talentstube.com/faire-offre-emploi-video" className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<a href={publicRuntimeConfig.symphonyUrl } className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<SupervisorAccountIcon className={classes.icon} />
|
||||
<ListItemText classes={{ primary: classes.ListItemText }} primary='Recruteurs'>
|
||||
</ListItemText>
|
||||
@@ -430,7 +424,7 @@ class Header extends React.Component {
|
||||
<List>
|
||||
<Link href="/" >
|
||||
<a className={classes.darkMenuItem + ' cypFrontPage'}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<img alt="talents-tube" src='/static/images/logos/TalentsTube_logo-blanc.svg' className={classes.menuLogo} />
|
||||
<img alt="talents-tube" src='/statique/images/logos/TalentsTube_logo-blanc.svg' className={classes.menuLogo} />
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
|
||||
@@ -458,7 +452,7 @@ class Header extends React.Component {
|
||||
<Divider light={true} />
|
||||
|
||||
<div className={classes.linkGroup}>
|
||||
<a href="https://www.talentstube.com/faire-offre-emploi-video" className={classes.lightMenuItem}><ListItem classes={{ primary: classes.ListItemText }} classes={{ root: classes.rootListItemIcon }}>
|
||||
<a href={publicRuntimeConfig.symphonyUrl + "/faire-offre-emploi-video"} className={classes.lightMenuItem}><ListItem classes={{ primary: classes.ListItemText }} classes={{ root: classes.rootListItemIcon }}>
|
||||
<WorkOutlineIcon className={classes.icon} />
|
||||
<ListItemText primary='Connexion recruteurs'>
|
||||
</ListItemText>
|
||||
@@ -470,7 +464,7 @@ class Header extends React.Component {
|
||||
{!!!this.props.loading && !!this.props.fetched &&
|
||||
<Fragment>
|
||||
{this.props.user.picture ?
|
||||
<img alt="talents-tube" src={`http://localhost/uploads/img/${this.props.user.picture}`} className={classes.menuAvatar} />
|
||||
<img alt="talents-tube" src={publicRuntimeConfig.symphonyUrl +publicRuntimeConfig.postedContentUrl+ this.props.user.picture} className={classes.menuAvatar} />
|
||||
:
|
||||
<img alt="talents-tube" src='/static/images/default/account-avatar-default.svg' className={classes.menuAvatar} />
|
||||
}
|
||||
@@ -494,17 +488,18 @@ class Header extends React.Component {
|
||||
</ListItemText>
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
<Link href="" >
|
||||
<a onClick={this.onRedirectAccount} className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<Link href="/profileStep" >
|
||||
<a className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<AccountCircleIcon className={classes.icon} />
|
||||
<ListItemText primary='Mon compte'>
|
||||
</ListItemText>
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
|
||||
<Link href="/Parametres" >
|
||||
<a className={classes.lightMenuItem}><ListItem classes={{ root: classes.rootListItemIcon }}>
|
||||
<SettingsIcon className={classes.icon} />
|
||||
<ListItemText primary='Paramètres'>
|
||||
<ListItemText primary='Paramètres de notification'>
|
||||
</ListItemText>
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
@@ -530,7 +525,7 @@ class Header extends React.Component {
|
||||
<Link href="/" >
|
||||
<a className={classes.darkMenuItem}>
|
||||
<ListItem classes={{ root: classes.rootListItemDesktop }}>
|
||||
<img alt="talents-tube" src='/static/images/logos/TalentsTube_logo-color.svg' className={classes.desktopMenuLogo} />
|
||||
<img alt="talents-tube" src='/statique/images/logos/TalentsTube_logo-color.svg' className={classes.desktopMenuLogo} />
|
||||
</ListItem>
|
||||
</a>
|
||||
</Link>
|
||||
@@ -610,7 +605,7 @@ class Header extends React.Component {
|
||||
</section>
|
||||
<section className={classes.appBarDesktopSection + ' ' + classes.appBarDesktopSection3}>
|
||||
|
||||
<a href="https://www.talentstube.com/faire-offre-emploi-video" className={classes.desktopMenuItem}>
|
||||
<a href={publicRuntimeConfig.symphonyUrl + "/faire-offre-emploi-video"} className={classes.desktopMenuItem}>
|
||||
<ListItemText primary='Espace recruteurs'>
|
||||
</ListItemText>
|
||||
<ArrowForward className={classes.icon} />
|
||||
@@ -628,7 +623,7 @@ class Header extends React.Component {
|
||||
</IconButton>
|
||||
<div className={classes.grow} />
|
||||
<Link href="/" >
|
||||
<a><img alt="talents-tube" src='/static/images/logos/TalentsTube_logo-color.svg' className={classes.menuLogo} /></a>
|
||||
<a><img alt="talents-tube" src='/statique/images/logos/TalentsTube_logo-color.svg' className={classes.menuLogo} /></a>
|
||||
</Link>
|
||||
<div className={classes.grow} />
|
||||
<IconButton
|
||||
|
||||
@@ -18,6 +18,8 @@ import Link from 'next/link'
|
||||
import withWidth, { isWidthUp } from '@material-ui/core/withWidth'
|
||||
import VideoVimeo from '../atoms/VideoVimeo'
|
||||
import OgHead from '../atoms/OgHead'
|
||||
import JobPosting from '../atoms/JobPosting'
|
||||
import Moment from 'react-moment';
|
||||
|
||||
const styles = theme => ({
|
||||
primary: {
|
||||
@@ -155,7 +157,7 @@ const styles = theme => ({
|
||||
objectFit: 'contain',
|
||||
},
|
||||
title: {
|
||||
fontSize: '1em',
|
||||
fontSize: '1.3em',
|
||||
fontWeight: '500',
|
||||
[theme.breakpoints.up('md')]: {
|
||||
paddingTop: theme.spacing(2),
|
||||
@@ -163,7 +165,7 @@ const styles = theme => ({
|
||||
},
|
||||
offreTitle: {
|
||||
[theme.breakpoints.up('md')]: {
|
||||
fontSize: '1.2em',
|
||||
fontSize: '1.3em',
|
||||
fontWeight: '600',
|
||||
},
|
||||
},
|
||||
@@ -190,7 +192,7 @@ const styles = theme => ({
|
||||
textAlign: 'center',
|
||||
},
|
||||
companyName: {
|
||||
fontSize: '0.9em',
|
||||
fontSize: '1.3em',
|
||||
fontWeight: '300',
|
||||
[theme.breakpoints.up('md')]: {
|
||||
fontSize: '1em',
|
||||
@@ -209,18 +211,18 @@ const styles = theme => ({
|
||||
},
|
||||
iconTextIcon: {
|
||||
color: theme.palette.offerlistitem.icon,
|
||||
fontSize: '1em',
|
||||
fontSize: '1.3em',
|
||||
},
|
||||
iconTextText: {
|
||||
fontWeight: 'lighter',
|
||||
color: theme.palette.offerlistitem.text,
|
||||
fontSize: '0.7em',
|
||||
fontSize: '1em',
|
||||
paddingLeft: theme.spacing(1),
|
||||
},
|
||||
iconTextTextDesktop: {
|
||||
fontWeight: 'lighter',
|
||||
color: theme.palette.offerlistitem.text,
|
||||
fontSize: '0.7em',
|
||||
fontSize: '1em',
|
||||
paddingLeft: theme.spacing(1),
|
||||
width: '100%',
|
||||
},
|
||||
@@ -297,18 +299,27 @@ function OffreDetail(props) {
|
||||
const DefaultUrl = "/static/images/default/default_picture_company.svg"
|
||||
const imgUrl = (offre.company && offre.company.presentation_video && offre.company.presentation_video.thumbnails && offre.company.presentation_video.thumbnails[0] && offre.company.presentation_video.thumbnails[0].sizes[2]) ? offre.company.presentation_video.thumbnails[0].sizes[2].link : DefaultUrl
|
||||
const imgUrlDesktop = (offre.company && offre.company.presentation_video && offre.company.presentation_video.thumbnails && offre.company.presentation_video.thumbnails[0] && offre.company.presentation_video.thumbnails[0].sizes[4]) ? offre.company.presentation_video.thumbnails[0].sizes[4].link : DefaultUrl
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location : publicRuntimeConfig.frontServerUrl + `/Offre/${offre.id}-${_.kebabCase(offre.title)}-${_.kebabCase(offre.location.gmap_address.name)}`;
|
||||
const entrepriseLink = (offre.company && `/Entreprise/${offre.company.id}-${_.kebabCase(offre.company.brand_name)}-${_.kebabCase(offre.location.gmap_address.name)}`);
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location : publicRuntimeConfig.frontServerUrl + `/Offre/${offre.id}-${_.kebabCase(offre.title)}`;
|
||||
const entrepriseLink = (offre.company && `/Entreprise/${offre.company.id}-${_.kebabCase(offre.company.brand_name)}`);
|
||||
const territoryVideoUrlTab = (offre.territories && offre.territories[0] && offre.territories[0].territory) ? offre.territories[0].territory.presentation_video.cdn_url.split('/') : '';
|
||||
const territoryVideoId = territoryVideoUrlTab[2]
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<OgHead seo_title={offre.title}
|
||||
seo_description={offre.description}
|
||||
seo_url={socialShareUrl}
|
||||
image={imgUrlDesktop}
|
||||
></OgHead>
|
||||
<JobPosting job_title={offre.title}
|
||||
job_description={offre.description}
|
||||
job_brand= {offre.company.brand_name && offre.company.brand_name}
|
||||
job_brand_link= {entrepriseLink}
|
||||
job_title = {offre.title}
|
||||
job_location = {offre.location.gmap_address.formatted_address}
|
||||
job_date = {offre.published_at}
|
||||
></JobPosting>
|
||||
{offre.video && (
|
||||
<Fragment>
|
||||
<Hidden smDown>
|
||||
@@ -319,17 +330,17 @@ function OffreDetail(props) {
|
||||
<div className={classes.logoContainer}>
|
||||
|
||||
<Avatar className={classes.logo} classes={{ img: classes.MuiAvatarImg }}
|
||||
src={logoUrl} alt="companyLogo" />
|
||||
src={logoUrl} alt={offre.company.brand_name && offre.company.brand_name} />
|
||||
|
||||
</div>
|
||||
</a>
|
||||
<div className={classes.infoContainer}>
|
||||
<Typography gutterBottom className={classes.offreTitle}>
|
||||
{offre.title}
|
||||
{offre.title} {/*- publié le <Moment format="DD/MM/YYYY" date={offre.published_at} /> */}
|
||||
</Typography>
|
||||
<a href={entrepriseLink} >
|
||||
<Typography gutterBottom variant="subtitle1" className={classes.companyName}>
|
||||
{offre.company.brand_name && offre.company.brand_name}
|
||||
{offre.company.brand_name ? offre.company.brand_name : ""}
|
||||
</Typography>
|
||||
</a>
|
||||
{offre.is_promoted && (
|
||||
@@ -390,6 +401,7 @@ function OffreDetail(props) {
|
||||
<section className={classes.IconTextContainerDesktop}>
|
||||
<IconTextInline classes={{ icon: classes.iconTextIcon, text: classes.iconTextText }} variant="assignment" text={offre.extra.contract_type} />
|
||||
<IconTextInline classes={{ icon: classes.iconTextIcon, text: classes.iconTextText }} variant="location_on" text={offre.location.gmap_address.formatted_address} />
|
||||
{offre.beneficiaire && (<IconTextInline classes={{ icon: classes.iconTextIcon, text: classes.iconTextText }} variant="business" text={offre.beneficiaire} /> )}
|
||||
</section>
|
||||
</Hidden>
|
||||
<SimpleCollapse>
|
||||
@@ -413,7 +425,7 @@ function OffreDetail(props) {
|
||||
variant="contained"
|
||||
className={classes.button}
|
||||
|
||||
>Postuler ! </Button>
|
||||
>Postuler</Button>
|
||||
</Link>
|
||||
<Typography className={classes.contentCondition}>
|
||||
ou
|
||||
@@ -437,7 +449,7 @@ function OffreDetail(props) {
|
||||
|
||||
<a href={entrepriseLink}>
|
||||
<div className={classes.discoverContainerImage}>
|
||||
<img src={isWidthUp('sm', props.width) ? imgUrlDesktop : imgUrl} alt="company" />
|
||||
<img src={isWidthUp('sm', props.width) ? imgUrlDesktop : imgUrl} alt={offre.company.brand_name && offre.company.brand_name} />
|
||||
<KeyboardArrowleftIcon className={classes.iconPlay} />
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -51,14 +51,15 @@ const styles = theme => ({
|
||||
alignItems: 'flex-start',
|
||||
padding: theme.spacing(2),
|
||||
width: '75%',
|
||||
// minHeight: '200px',
|
||||
},
|
||||
jobTitle: {
|
||||
fontSize: '1em',
|
||||
fontSize: '1.2em',
|
||||
fontWeight: 'bold',
|
||||
color: theme.palette.offerlistitem.title,
|
||||
},
|
||||
companyTitle: {
|
||||
fontSize: '0.8em',
|
||||
fontSize: '1.2em',
|
||||
fontWeight: '300',
|
||||
color: theme.palette.offerlistitem.title,
|
||||
},
|
||||
@@ -96,11 +97,11 @@ const styles = theme => ({
|
||||
},
|
||||
iconTextIcon: {
|
||||
color: theme.palette.offerlistitem.icon,
|
||||
fontSize: '0.8em',
|
||||
fontSize: '1.2em',
|
||||
},
|
||||
iconTextText: {
|
||||
color: theme.palette.offerlistitem.text,
|
||||
fontSize: '0.6em',
|
||||
fontSize: '1em',
|
||||
paddingLeft: theme.spacing(1),
|
||||
},
|
||||
chip: {
|
||||
@@ -126,7 +127,7 @@ class OffreRowComponent extends React.Component {
|
||||
const imgUrl = (rowData.video && rowData.video.thumbnails && rowData.video.thumbnails[0] && rowData.video.thumbnails[0].sizes[4]) ? rowData.video.thumbnails[0].sizes[4].link : publicRuntimeConfig.adListDefaultUrl
|
||||
|
||||
return (
|
||||
<Link href={`/Offre/${rowData.id}-${_.kebabCase(rowData.title)}-${_.kebabCase(rowData.location.gmap_address.name)}`} >
|
||||
<Link href={`/Offre/${rowData.id}-${_.kebabCase(rowData.title)}`} >
|
||||
<Card className={classes.card + ' cypCardOffre'} >
|
||||
<CardContent className={classes.content}>
|
||||
<CardMedia
|
||||
@@ -144,14 +145,14 @@ class OffreRowComponent extends React.Component {
|
||||
variant="h6"
|
||||
component="h3"
|
||||
className={classes.jobTitle}>
|
||||
{rowData.title}
|
||||
{rowData.title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="headline"
|
||||
variant="h6"
|
||||
component="h4"
|
||||
component="h3"
|
||||
className={classes.companyTitle}>
|
||||
{!!companyR.brand_name?companyR.brand_name:"-"}
|
||||
{companyR.brand_name ? companyR.brand_name : "Non renseigné"}
|
||||
</Typography>
|
||||
<div>
|
||||
{rowData.is_promoted && (
|
||||
@@ -160,8 +161,10 @@ class OffreRowComponent extends React.Component {
|
||||
|
||||
{!rowData.is_promoted && (
|
||||
<Fragment>
|
||||
<IconText classes={{ root: classes.iconText, icon: classes.iconTextIcon, text: classes.iconTextText }} variant="location_on" text={rowData.extra.contract_type} />
|
||||
<IconText classes={{ root: classes.iconText, icon: classes.iconTextIcon, text: classes.iconTextText }} variant="business_center" text={rowData.location.gmap_address.formatted_address} />
|
||||
<IconText classes={{ root: classes.iconText, icon: classes.iconTextIcon, text: classes.iconTextText }} variant="business_center" text={rowData.extra.contract_type} />
|
||||
<IconText classes={{ root: classes.iconText, icon: classes.iconTextIcon, text: classes.iconTextText }} variant="location_on" text={rowData.location.gmap_address.formatted_address} />
|
||||
{rowData.beneficiaire ? <IconText classes={{ root: classes.iconText, icon: classes.iconTextIcon, text: classes.iconTextText }} variant="business" text={rowData.beneficiaire} /> : ""}
|
||||
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
|
||||
@@ -130,7 +130,15 @@ class Recorder extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
const { classes, titreBouton } = this.props;
|
||||
let titreButtonLabel= "Envoyer";
|
||||
|
||||
|
||||
if (titreBouton) {
|
||||
titreButtonLabel = titreBouton;
|
||||
console.log("titre");
|
||||
console.log(titreButtonLabel);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div data-vjs-player>
|
||||
@@ -140,7 +148,7 @@ class Recorder extends Component {
|
||||
{ this.state.canSend && <Button type="submit" variant="outlined" color="primary"
|
||||
className={classes.button}
|
||||
onClick={this.sendBlob}>
|
||||
Envoyer
|
||||
{titreButtonLabel}
|
||||
</Button>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import withWidth, { isWidthUp } from '@material-ui/core/withWidth'
|
||||
|
||||
import VideoVimeo from '../atoms/VideoVimeo'
|
||||
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
position: 'relative',
|
||||
@@ -169,7 +170,7 @@ class ShortVideoHooker extends Component {
|
||||
|
||||
return (
|
||||
<div className={classes.video}>
|
||||
<VideoVimeo classesOverride={ classes.videoVimeo } videoId={videoList[this.state.i].vimeoId} title={videoList[this.state.i].title}
|
||||
{/* <VideoVimeo classesOverride={ classes.videoVimeo } videoId={videoId}
|
||||
options={`?byline=0&title=0&background=1&autoplay=1&mute=1`} />
|
||||
<section className={classes.text}>
|
||||
<Typography gutterBottom
|
||||
@@ -199,7 +200,7 @@ class ShortVideoHooker extends Component {
|
||||
>
|
||||
Voir l'offre
|
||||
</Button>
|
||||
</Link>
|
||||
</Link> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class Tile extends React.Component {
|
||||
const logoName = (rowData.company) ? rowData.company.logo : rowData.logo
|
||||
const logoUrl = publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + logoName
|
||||
|
||||
const router = (rowData.company) ? `/Offre/${rowData.id}-${_.kebabCase(rowData.title)}-${_.kebabCase(rowData.location.gmap_address.name)}` : `/Entreprise/${rowData.id}-${_.kebabCase(rowData.brand_name)}-${_.kebabCase(rowData.addresses.billing.city)}`
|
||||
const router = (rowData.company) ? `/Offre/${rowData.id}-${_.kebabCase(rowData.title)}` : `/Entreprise/${rowData.id}-${_.kebabCase(rowData.brand_name)}}`
|
||||
|
||||
//rowData._embedded.company.brand_name
|
||||
return (
|
||||
@@ -113,7 +113,7 @@ class Tile extends React.Component {
|
||||
/>
|
||||
<KeyboardArrowleftIcon className={classes.iconPlay} />
|
||||
<div className={classes.logoContainer}>
|
||||
<Avatar className={classes.logo} src={logoUrl} alt="company"/>
|
||||
<Avatar className={classes.logo} src={logoUrl} alt={rowData.title}/>
|
||||
</div>
|
||||
{ children }
|
||||
</CardContent>
|
||||
|
||||
@@ -10,11 +10,11 @@ const styles = theme => ({
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
position: 'absolute',
|
||||
top: '51%',
|
||||
top: '44%',
|
||||
width: '100%',
|
||||
},
|
||||
companyTitle: {
|
||||
fontSize: '0.8em',
|
||||
fontSize: '1em',
|
||||
fontWeight: '100',
|
||||
padding: theme.spacing(0, 2),
|
||||
marginTop: '4vh',
|
||||
@@ -24,7 +24,7 @@ const styles = theme => ({
|
||||
},
|
||||
},
|
||||
jobTitle: {
|
||||
fontSize: '1em',
|
||||
fontSize: '1.2em',
|
||||
padding: theme.spacing(0, 2),
|
||||
minHeight: '8vh',
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
@@ -59,7 +59,7 @@ class TileOffre extends React.Component {
|
||||
component="h4"
|
||||
align="center"
|
||||
className={classes.companyTitle}>
|
||||
{tile.company.brand_name && tile.company.brand_name}
|
||||
{tile.company.brand_name && tile.company.brand_name}
|
||||
</Typography>
|
||||
<Typography
|
||||
gutterBottom
|
||||
@@ -82,6 +82,10 @@ class TileOffre extends React.Component {
|
||||
{tile.extra && tile.extra.contract_type &&
|
||||
<IconText classes={{ root: classes.rootIconText }} variant="assignment" text={tile.extra.contract_type} />
|
||||
}
|
||||
|
||||
{tile.beneficiaire &&
|
||||
<IconText classes={{ root: classes.rootIconText }} variant="business" text={tile.beneficiaire} />
|
||||
}
|
||||
</section>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
@@ -67,17 +67,17 @@ export default {
|
||||
},
|
||||
},
|
||||
ads: {
|
||||
fetchAd: (id) => {
|
||||
return axios.get(`api/ads/${id}`).then(res => res.data)
|
||||
fetchJob: (id) => {
|
||||
return axios.get(`api/jobs/${id}`).then(res => res.data)
|
||||
},
|
||||
|
||||
//offset is the index position of the first element to start requesting at
|
||||
// use 0|1 for isPromoted
|
||||
fetchAds: ({ limit = null, order = "", keyword = "", offset = 1, status = 'PUBLISHED', isPromoted = null, isEmphasis = null }) => {
|
||||
fetchJobs: ({ limit = null, order = "", keyword = "", offset = 1, status = 'PUBLISHED', isPromoted = false, isEmphasis = false }) => {
|
||||
isPromoted = isPromoted !== null ? isPromoted * 1 : isPromoted;
|
||||
isEmphasis = isEmphasis !== null ? isEmphasis * 1 : isEmphasis;
|
||||
|
||||
return axios.get('api/ads', { params: { offset, limit, order, keyword, status, isPromoted, isEmphasis } })
|
||||
return axios.get('api/jobs', { params: { offset, limit, order, keyword, status, isPromoted, isEmphasis } })
|
||||
.then(res => res.data)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export default {
|
||||
postAnswer: (payload) => {
|
||||
return axios.post("/api/answers", { adId: payload.adId, mediaId: payload.mediaId, companyId: payload.companyId }).then(res => res)
|
||||
},
|
||||
fetchAdsAnswered: ({ limit = null, order = "", keyword = "", offset = 1 }) => {
|
||||
fetchJobsAnswered: ({ limit = null, order = "", keyword = "", offset = 1 }) => {
|
||||
return axios.get(`api/answers`, { params: { offset, limit, order, keyword } }).then(res => res.data)
|
||||
},
|
||||
fetchAnswer: (payload) => {
|
||||
@@ -120,6 +120,22 @@ export default {
|
||||
withCredentials: true
|
||||
}).then(res => res)
|
||||
},
|
||||
uploadMediaPres: (payload) => {
|
||||
return axios.post("/api/mediaPres", payload, {
|
||||
headers: {
|
||||
'Content-Type': `multipart/form-data;`
|
||||
},
|
||||
withCredentials: true
|
||||
}).then(res => res)
|
||||
},
|
||||
uploadMediaCv: (payload) => {
|
||||
return axios.post("/api/mediaCv", payload, {
|
||||
headers: {
|
||||
'Content-Type': `multipart/form-data;`
|
||||
},
|
||||
withCredentials: true
|
||||
}).then(res => res)
|
||||
}
|
||||
},
|
||||
stats: {
|
||||
countAdView: id => {
|
||||
@@ -135,4 +151,4 @@ export default {
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
@@ -33,21 +33,25 @@ module.exports = withPlugins(
|
||||
}
|
||||
],
|
||||
importScripts:
|
||||
['/static/js/Edeclic-service-worker.js',
|
||||
'/static/js/backgroundSync-sw.js'
|
||||
['/statique/js/Edeclic-service-worker.js',
|
||||
'/statique/js/backgroundSync-sw.js'
|
||||
]
|
||||
},
|
||||
}],
|
||||
[{
|
||||
publicRuntimeConfig: {
|
||||
symphonyUrl: 'https://www.talentstube.com',
|
||||
frontServerUrl: 'https://pp.app.talentstube.com',
|
||||
adListDefaultUrl: '/static/images/default/default_picture_company.svg',
|
||||
symphonyUrl: 'https://recruteur.talentstube.com',
|
||||
blogUrl: 'https://blog.talentstube.com',
|
||||
frontServerUrl: 'https://www.talentstube.com',
|
||||
cvThequeUrl: 'https://cvtheque.talentstube.com/',
|
||||
adListDefaultUrl: '/statique/images/default/default_picture_company.svg',
|
||||
cachedMediaUrl: '/media/cache/profile_thumb/uploads/img/',
|
||||
postedContentUrl: '/uploads/img/',
|
||||
postedContentCv: '/uploads/cv/',
|
||||
ReCAPTCHA: {
|
||||
"siteKey": "6LdyqLwUAAAAADKI5uC7d5W9VqVgzd8VEmMU2Yi-"
|
||||
},
|
||||
applicationServerPublicKey: 'BNFyiyPiLH97Dgc0m1vXluUNaCN6y3Hkgd4YcqS2lVkP8my3tq2D5gM5g7cY6R4VxC7GljSzkLRu+k+oO+2TtjU='
|
||||
}
|
||||
}]
|
||||
],
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@blunck/next-alias": "^1.0.0",
|
||||
"@material-ui/core": "^4.2.0",
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"@material-ui/core": "^4.9.10",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||
"@ostai/next-css": "^1.0.2",
|
||||
"axios": "^0.18.0",
|
||||
"connect-mongo": "^2.0.1",
|
||||
@@ -33,6 +34,7 @@
|
||||
"next-optimized-images": "^1.4.1",
|
||||
"next-redux-saga": "^4.0.2",
|
||||
"next-redux-wrapper": "^3.0.0-alpha.2",
|
||||
"next-seo": "^4.7.3",
|
||||
"next-transpile-modules": "^2.3.1",
|
||||
"node-mailjet": "^3.3.1",
|
||||
"nodemailer": "^4.6.8",
|
||||
@@ -44,10 +46,13 @@
|
||||
"passport-oauth2": "https://github.com/Huaoe/passport-oauth2.git",
|
||||
"prop-types": "latest",
|
||||
"react": "^16.9.0",
|
||||
"react-ad-block-detect": "^1.0.1",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-ga": "^2.5.7",
|
||||
"react-google-recaptcha": "^2.0.1",
|
||||
"react-html-parser": "^2.0.2",
|
||||
"react-jss": "latest",
|
||||
"react-moment": "^0.9.7",
|
||||
"react-redux": "^7.0.3",
|
||||
"react-swipeable-views": "^0.13.3",
|
||||
"reactstrap": "^6.4.0",
|
||||
|
||||
@@ -147,6 +147,7 @@ class Candidature extends React.Component {
|
||||
<LayoutCandidature>
|
||||
<Head>
|
||||
<title key="title">Candidature</title>
|
||||
<meta name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
<Fragment>
|
||||
<div className={classes.container}>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Layout from "../components/templates/Layout";
|
||||
import AccountProfileCandidature from "../components/organisms/AccountProfileCandidature";
|
||||
import Head from 'next/head'
|
||||
// import AdBlockDetect from 'react-ad-block-detect';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
width: '100%',
|
||||
},
|
||||
button: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
completed: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
instructions: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
|
||||
export default function HorizontalNonLinearStepper() {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Head>
|
||||
<title key="title">Profile – Talents Tube</title>
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
<div >
|
||||
<AccountProfileCandidature />
|
||||
</div>
|
||||
|
||||
{/* <AdBlockDetect>
|
||||
<p>AdBlocks a été détecté. Pour que Talents Tube puisse fonctionner correctement, veuillez désactiver Ad Blocks</p>
|
||||
</AdBlockDetect> */}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -8,9 +8,10 @@ import { Typography } from '@material-ui/core';
|
||||
import LayoutGrid from "../components/templates/LayoutGrid";
|
||||
import Grid from "../components/templates/Grid"
|
||||
import AnswerRow from "../components/organisms/AnswerRow"
|
||||
import { fetchAdsAnsweredRequest } from '../actions/answer'
|
||||
import { fetchJobsAnsweredRequest } from '../actions/answer'
|
||||
import { AnswersSelector } from '../reducers/answers'
|
||||
import Head from 'next/head'
|
||||
import Link from 'next/link';
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
@@ -24,6 +25,13 @@ const styles = theme => ({
|
||||
flexDirection: 'column',
|
||||
padding: theme.spacing(0,3),
|
||||
},
|
||||
profil: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: theme.spacing(3,3),
|
||||
textAlign: 'center',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
},
|
||||
title: {
|
||||
fontFamily: 'Dosis',
|
||||
fontSize: '1.5em',
|
||||
@@ -45,16 +53,18 @@ class Candidatures extends React.Component {
|
||||
<LayoutGrid backLink="/">
|
||||
<Head>
|
||||
<title key="title">Candidatures</title>
|
||||
<meta name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
|
||||
{/* TODO */}
|
||||
<Typography component="h1" align="center" className={classes.title} gutterBottom>
|
||||
Mes candidatures
|
||||
</Typography>
|
||||
|
||||
<div className={classes.container}>
|
||||
|
||||
<Grid CustomRowComponent={AnswerRow}
|
||||
dataFetcher={this.props.fetchAdsAnsweredRequest}
|
||||
dataFetcher={this.props.fetchJobsAnsweredRequest}
|
||||
data={this.props.answers}
|
||||
currentPage={this.props.currentPage}
|
||||
recordCount={this.props.recordCount}
|
||||
@@ -63,6 +73,16 @@ class Candidatures extends React.Component {
|
||||
searchable={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</LayoutGrid>
|
||||
);
|
||||
}
|
||||
@@ -83,4 +103,4 @@ function mapStateToProps(state) {
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, {fetchAdsAnsweredRequest })(Candidatures))
|
||||
export default withStyles(styles)(connect(mapStateToProps, {fetchJobsAnsweredRequest })(Candidatures))
|
||||
|
||||
@@ -57,7 +57,7 @@ class Confidentialite extends Component {
|
||||
</Head>
|
||||
<div className={classes.container}>
|
||||
<Typography className={classes.text} gutterBottom align="left">
|
||||
Nous vous invitons à lire avec attention le présent document. Pour toute question concernant ce document et, d’une manière générale, sur la collecte et le traitement de vos informations personnelles par la société talentstube.com, n’hésitez pas à nous contacter via le formulaire présent sur la page contact : <a href="https://blog.talentstube.com/contact.html" className={classes.link} target="_blank">https://blog.talentstube.com/contact.html</a>
|
||||
Nous vous invitons à lire avec attention le présent document. Pour toute question concernant ce document et, d’une manière générale, sur la collecte et le traitement de vos informations personnelles par la société talentstube.com, n’hésitez pas à nous contacter via le formulaire présent sur la page contact : <a href="https://blog.talentstube.com/contact" className={classes.link} target="_blank">https://blog.talentstube.com/contact</a>
|
||||
</Typography>
|
||||
|
||||
<Typography className={classes.title} component="h2" gutterBottom align="left">
|
||||
@@ -155,7 +155,7 @@ class Confidentialite extends Component {
|
||||
`
|
||||
Vous disposez d'un droit d'accès, de rectification, de suppression, d’opposition et de portabilité des données. Nous disposons d’un délai de 30 jours à compter de votre demande pour apporter une réponse.
|
||||
Vous pouvez demander une limitation du traitement des données collectées. L’exercice de ces droits peut exercer ce droit auprès de TALENTS TUBE en adressant une requête soit par voie postale à l'adresse suivante : 3 Rue Louis de Broglie, Village By CA 56000 Vannes, soit par courrier électronique via le formulaire présent sur la page Contact `
|
||||
}<a href="https://blog.talentstube.com/contact.html" className={classes.link} target="_blank">https://blog.talentstube.com/contact.html</a>{`. Cette requête devra être accompagnée d'une pièce d'identité revêtant la signature de l'Utilisateur et devra préciser l'adresse et le moyen par lesquelles une réponse pourra être envoyée..
|
||||
}<a href="https://blog.talentstube.com/contact" className={classes.link} target="_blank">https://blog.talentstube.com/contact</a>{`. Cette requête devra être accompagnée d'une pièce d'identité revêtant la signature de l'Utilisateur et devra préciser l'adresse et le moyen par lesquelles une réponse pourra être envoyée..
|
||||
`
|
||||
}
|
||||
</Typography>
|
||||
@@ -178,7 +178,7 @@ class Confidentialite extends Component {
|
||||
<a href="http://windows.microsoft.com/fr-fr/internet-explorer/delete-manage-cookies#ie=ie-11" className={classes.link} target="_blank">Internet Explorer</a><br />
|
||||
|
||||
`
|
||||
Pour plus d’informations sur les cookies et la façon de les gérer, nous vous recommandons de consulter le site `} <a href="http://www.youronlinechoices.com/fr/" className={classes.link} target="_blank">www.youronlinechoices.com</a>{`, développé par l’organisme EDAA (European Interactive Digital Advertising Alliance).
|
||||
Pour plus d’informations sur les cookies et la façon de les gérer, nous vous recommandons de consulter le site ` <a href="http://www.youronlinechoices.com/fr/" className={classes.link} target="_blank">www.youronlinechoices.com</a>{`, développé par l’organisme EDAA (European Interactive Digital Advertising Alliance).
|
||||
`
|
||||
}
|
||||
</Typography>
|
||||
|
||||
@@ -12,7 +12,7 @@ const styles = theme => ({
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
padding: theme.spacing(3,2),
|
||||
padding: theme.spacing(3, 2),
|
||||
width: '100%',
|
||||
},
|
||||
vimeoVideo: {
|
||||
@@ -26,17 +26,17 @@ class Conseils extends React.Component {
|
||||
const { classes } = this.props
|
||||
|
||||
return (
|
||||
<LayoutBack text="Quelques conseils !">
|
||||
<LayoutBack text="Quelques conseils !">
|
||||
<Head>
|
||||
<title>Quelques conseils !</title>
|
||||
<meta name="description" content="Quelques conseils !" />
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
<link rel="canonical" href="https://app.talentstube.com" />
|
||||
|
||||
</Head>
|
||||
<section className={ classes.container }>
|
||||
<VideoVimeo videoId='356411947' autoplay='1'/>
|
||||
<section className={classes.container}>
|
||||
<VideoVimeo videoId='356411947' autoplay='1' />
|
||||
</section>
|
||||
</LayoutBack>
|
||||
</LayoutBack>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -357,9 +357,9 @@ class Entreprise extends React.Component {
|
||||
|
||||
render() {
|
||||
const { classes, company } = this.props;
|
||||
const logoUrl = (company.logo ? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + company.logo : "https://www.talentstube.com/img/default_picture_svg")
|
||||
const logoUrl = (company.logo ? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + company.logo : publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg")
|
||||
|
||||
const DefaultUrl = "https://www.talentstube.com/img/default_picture_svg"
|
||||
const DefaultUrl = publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg"
|
||||
const imgUrl = (company.presentation_video && company.presentation_video.thumbnails[0] && company.presentation_video.thumbnails[0].sizes[2]) ? company.presentation_video.thumbnails[0].sizes[2].link : DefaultUrl
|
||||
|
||||
const offre = (company.count_ads == 1) ? company.count_ads + ' offre' : company.count_ads + ' offres'
|
||||
@@ -384,11 +384,12 @@ class Entreprise extends React.Component {
|
||||
const { loading } = this.state;
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location
|
||||
: publicRuntimeConfig.frontServerUrl + `/Entreprise/${company.id}`;
|
||||
|
||||
const descriptionVille = company.addresses.billing.city ? company.addresses.billing.city : "";
|
||||
const descriptionCompany = company.brand_name ? company.brand_name : "";
|
||||
return (
|
||||
<LayoutCompany backLink="/Entreprises" companyId={company.id}>
|
||||
<OgHead seo_title={company.brand_name && company.brand_name}
|
||||
seo_description={company.description}
|
||||
<OgHead seo_title={company.brand_name && company.brand_name+" recrute des candidats en vidéo | Talents Tube"}
|
||||
seo_description={"Découvrez l'entreprise "+descriptionCompany +" et ses offres en vidéo - "+descriptionVille+ ". Envoyez votre candidature spontanée en vidéo."}
|
||||
seo_url={socialShareUrl}
|
||||
image={imgUrl}
|
||||
></OgHead>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import getConfig from 'next/config'
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import _ from "lodash"
|
||||
import Grid from "../components/templates/Grid"
|
||||
@@ -11,6 +12,7 @@ import { fetchCompaniesRequest } from '../actions/companies'
|
||||
import { CompaniesSelector } from '../reducers/companies'
|
||||
import { connect } from "react-redux";
|
||||
import Head from 'next/head'
|
||||
import OgHead from '../components/atoms/OgHead';
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
@@ -64,13 +66,41 @@ class Entreprises extends React.Component {
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location
|
||||
: publicRuntimeConfig.frontServerUrl + `/Entreprises`;
|
||||
const DefaultUrl = publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg"
|
||||
const imgUrl = DefaultUrl ;
|
||||
return (
|
||||
<LayoutGrid backLink="/">
|
||||
<Head>
|
||||
{/* <Head>
|
||||
<title key="title">Entreprises qui recrutent – Talents Tube</title>
|
||||
<meta name="description" content="Les entreprises en vidéo." />
|
||||
</Head>
|
||||
|
||||
<meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:site" content="@TalentsTube"/>
|
||||
<meta name="twitter:title" content="Les entreprises qui recrutent en vidéo | TalentsTube"/>
|
||||
<meta name="twitter:description" content="Découvrez les entreprises qui recrutent en vidéo, elles dévoilent leurs marques employeur et leurs offres d'emploi en vidéo. Postulez rapidement à l'offre qui vous convient."/>
|
||||
<meta name="twitter:image" content=""/>
|
||||
|
||||
|
||||
<meta property="og:title" content="Les entreprises qui recrutent en vidéo | TalentsTube"/>
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta property="og:image" content=""/>
|
||||
<meta property="og:description"
|
||||
content="Découvrez les entreprises qui recrutent en vidéo, elles dévoilent leurs marques employeur et leurs offres d'emploi en vidéo. Postulez rapidement à l'offre qui vous convient."/>
|
||||
<meta property="og:site_name" content="Talents Tube"/>
|
||||
<meta property="og:url"
|
||||
content=""/>
|
||||
|
||||
</Head> */}
|
||||
<OgHead seo_title="Vidéos marque employeur d'entreprises qui recrutent | Talents Tube"
|
||||
seo_description="Vidéos marque employeur d'entreprises qui recrutent, découvrez leurs offres d'emploi en vidéo. Postulez simplement en vidéo à l'offre de votre choix."
|
||||
seo_url={socialShareUrl}
|
||||
image={imgUrl}
|
||||
seo_key="Recrutement, video"
|
||||
|
||||
></OgHead>
|
||||
<Typography gutterBottom component="h1"
|
||||
className={classes.title}>
|
||||
Les entreprises en <span className={classes.primary}>vidéo</span>
|
||||
|
||||
@@ -8,8 +8,8 @@ import { withStyles } from '@material-ui/core/styles';
|
||||
import Layout from "../components/templates/Layout"
|
||||
import Footer from '../components/organisms/Footer';
|
||||
import Link from 'next/link';
|
||||
import Head from 'next/head'
|
||||
import VideoVimeo from './../components/atoms/VideoVimeo'
|
||||
import Head from 'next/head';
|
||||
import VideoVimeo from './../components/atoms/VideoVimeo';
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
@@ -102,6 +102,7 @@ function Help(props) {
|
||||
<Layout>
|
||||
<Head>
|
||||
<title key="title">Recrutement vidéo : fonctionnement – Talents Tube</title>
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
<section className={classes.root}>
|
||||
<Typography gutterBottom component="h1"
|
||||
@@ -120,7 +121,7 @@ function Help(props) {
|
||||
<img alt="talents-tube" src='/static/images/help/image-aide-web-app.svg' className={classes.teamworkingImg} />
|
||||
<Typography gutterBottom component="h2"
|
||||
className={classes.subTitle}>
|
||||
Découvrez les offres d'emploi en vidéo
|
||||
Comment postuler à une offre d’emploi en vidéo
|
||||
</Typography>
|
||||
<VideoVimeo videoId='356411947' classesOverride={classes.video} autoplay='0'/>
|
||||
<Typography
|
||||
@@ -130,13 +131,34 @@ function Help(props) {
|
||||
</Typography>
|
||||
<Typography gutterBottom component="h2"
|
||||
className={classes.subTitle}>
|
||||
Vous possédez déjà un CV vidéo ?
|
||||
Comment réussir votre CV vidéo
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.text}
|
||||
gutterBottom>
|
||||
Vous n'avez pas trouvé votre bonheur dans nos offres d'emploi, mais vous souhaitez diffuser votre <span className={classes.bold}>CV vidéo à l'ensemble de notre communauté de talents.</span> <br></br> Découvrez les vidéos de nos talents sur notre CV vidéothèque.
|
||||
Suivez ce <a href="https://blog.talentstube.com/faire-cv-video" target="_blank" >lien</a>
|
||||
</Typography>
|
||||
|
||||
<Typography gutterBottom component="h2"
|
||||
className={classes.subTitle}>
|
||||
Accompagnement à la création d'un CV vidéo professionnel
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.text}
|
||||
gutterBottom>
|
||||
Suivez ce <a href="https://blog.talentstube.com/accompagnement-cv-video" target="_blank" >lien</a>
|
||||
</Typography>
|
||||
|
||||
<Typography gutterBottom component="h2"
|
||||
className={classes.subTitle}>
|
||||
Pourquoi faire un CV vidéo ?
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.text}
|
||||
gutterBottom>
|
||||
Suivez ce <a href="https://blog.talentstube.com/faire-cv-video" target="_blank" >lien</a>
|
||||
</Typography>
|
||||
|
||||
|
||||
</section>
|
||||
<Footer />
|
||||
|
||||
@@ -6,7 +6,7 @@ import getConfig from 'next/config'
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import LayoutOffre from "../components/templates/LayoutOffre";
|
||||
import OffreDetail from "../components/organisms/OffreDetail";
|
||||
import { fetchAdRequest, clearAd, countAdViewRequest } from '../actions/ads'
|
||||
import { fetchJobRequest, clearAd, countAdViewRequest } from '../actions/ads'
|
||||
import _ from "lodash/string";
|
||||
|
||||
const styles = theme => ({
|
||||
@@ -42,7 +42,7 @@ class Offre extends React.Component {
|
||||
Offre.getInitialProps = function (context) {
|
||||
const { id } = context.query
|
||||
|
||||
context.store.dispatch(fetchAdRequest(id))
|
||||
context.store.dispatch(fetchJobRequest(id))
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -57,4 +57,4 @@ Offre.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchAdRequest, clearAd, countAdViewRequest})(Offre));
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchJobRequest, clearAd, countAdViewRequest})(Offre));
|
||||
|
||||
@@ -9,10 +9,12 @@ import LayoutGrid from "../components/templates/LayoutGrid";
|
||||
import Grid from "../components/templates/Grid"
|
||||
import OffreRow from "../components/organisms/OffreRow"
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { fetchAdsRequest, togglePromotedFilterRequest} from '../actions/ads'
|
||||
import { fetchJobsRequest, togglePromotedFilterRequest} from '../actions/ads'
|
||||
import { AdsSelector } from '../reducers/ads'
|
||||
import { TextField } from '@material-ui/core';
|
||||
import Head from 'next/head'
|
||||
import OgHead from '../components/atoms/OgHead';
|
||||
import getConfig from 'next/config'
|
||||
|
||||
|
||||
const styles = theme => ({
|
||||
@@ -84,14 +86,20 @@ class Offres extends React.Component {
|
||||
const { classes } = this.props;
|
||||
const countColor = this.props.promotedFilter ? classes.provided : classes.primary;
|
||||
const btnClass = this.props.promotedFilter ? classes.buttonDefault : classes.buttonProvided;
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location
|
||||
: publicRuntimeConfig.frontServerUrl + `/Offres`;
|
||||
const DefaultUrl = publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg"
|
||||
const imgUrl = DefaultUrl ;
|
||||
return (
|
||||
<LayoutGrid backLink="/">
|
||||
<Head>
|
||||
<title key="title">Offres d’emploi en vidéo – Talents Tube</title>
|
||||
<meta name="description" content="Les offres d'emploi en vidéo." />
|
||||
|
||||
</Head>
|
||||
<OgHead seo_title="Vidéos d'offres d'emploi, CDI, CDD, alternance et Stage | Talents Tube"
|
||||
seo_description="Vidéos d'offres d'emploi, CDI, CDD, alternance, stage et apprentissage d'entreprises qui recrutent sur Talents Tube."
|
||||
seo_url={socialShareUrl}
|
||||
image={imgUrl}
|
||||
seo_key="Recrutement, video"
|
||||
|
||||
></OgHead>
|
||||
|
||||
<Typography gutterBottom component="h1"
|
||||
className={classes.title}>
|
||||
@@ -99,7 +107,7 @@ class Offres extends React.Component {
|
||||
</Typography>
|
||||
<div className={classes.container}>
|
||||
<Grid CustomRowComponent={OffreRow}
|
||||
dataFetcher={this.props.fetchAdsRequest}
|
||||
dataFetcher={this.props.fetchJobsRequest}
|
||||
data={this.props.ads}
|
||||
currentPage={this.props.currentPage}
|
||||
recordCount={this.props.recordCount}
|
||||
@@ -140,4 +148,4 @@ function mapStateToProps(state) {
|
||||
};
|
||||
}
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchAdsRequest, togglePromotedFilterRequest })(Offres))
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchJobsRequest, togglePromotedFilterRequest })(Offres))
|
||||
|
||||
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
||||
import Stepper from '@material-ui/core/Stepper';
|
||||
import Step from '@material-ui/core/Step';
|
||||
import StepLabel from '@material-ui/core/StepLabel';
|
||||
import { fetchAdRequest } from '../actions/ads'
|
||||
import { fetchJobRequest } from '../actions/ads'
|
||||
import { fetchCompanyRequest } from '../actions/companies'
|
||||
import { fetchCurrentUserRequest } from '../actions/user'
|
||||
import { uploadMedia } from '../actions/media'
|
||||
@@ -282,7 +282,7 @@ class Reponse extends React.Component {
|
||||
<title>Candidature vidéo</title>
|
||||
<meta name="description" content="Talent's tube, postulez en video." />
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
<link rel="canonical" href="https://app.talentstube.com" />
|
||||
|
||||
</Head>
|
||||
{/* https://codesandbox.io/s/ii0us */}
|
||||
{ loading ?
|
||||
@@ -429,7 +429,7 @@ Reponse.getInitialProps = function (context) {
|
||||
context.store.dispatch(fetchCurrentUserRequest())
|
||||
|
||||
if(!!adId)
|
||||
context.store.dispatch(fetchAdRequest(adId))
|
||||
context.store.dispatch(fetchJobRequest(adId))
|
||||
else if(!!companyId)
|
||||
context.store.dispatch(fetchCompanyRequest(companyId))
|
||||
|
||||
@@ -452,4 +452,4 @@ Reponse.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchCurrentUserRequest, fetchAdRequest, fetchCompanyRequest, uploadMedia })(Reponse));
|
||||
export default withStyles(styles)(connect(mapStateToProps, { fetchCurrentUserRequest, fetchJobRequest, fetchCompanyRequest, uploadMedia })(Reponse));
|
||||
@@ -107,6 +107,7 @@ class ResetPassword extends Component {
|
||||
<Layout>
|
||||
<Head>
|
||||
<title key="title">Reset password</title>
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
<div className={classes.container}>
|
||||
<Typography
|
||||
|
||||
@@ -8,17 +8,19 @@ import { Typography } from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Router from 'next/router'
|
||||
import { connect } from 'react-redux'
|
||||
import { fetchEmphasisAdsRequest } from "../actions/ads";
|
||||
import { fetchEmphasisJobsRequest } from "../actions/ads";
|
||||
import { fetchEmphasisCompaniesRequest } from "../actions/companies";
|
||||
import Loader from './../components/templates/loader'
|
||||
import { isEmpty } from "lodash"
|
||||
import NoResult from './../components/atoms/NoResult';
|
||||
import Head from 'next/head'
|
||||
import dynamic from 'next/dynamic'
|
||||
import OgHead from '../components/atoms/OgHead';
|
||||
import getConfig from 'next/config'
|
||||
|
||||
const VideoSlider = dynamic(() => import('../components/organisms/ShortVideoHooker'), {
|
||||
ssr: false
|
||||
});
|
||||
// const VideoSlider = dynamic(() => import('../components/organisms/ShortVideoHooker'), {
|
||||
// ssr: false
|
||||
// });
|
||||
const HorizontalScroller = dynamic(() => import('../components/organisms/HorizontalScroller'), {
|
||||
ssr: false
|
||||
});
|
||||
@@ -34,7 +36,7 @@ const TileOffre = dynamic(() => import('../components/organisms/TileOffre'), {
|
||||
const Footer = dynamic(() => import('../components/organisms/Footer'), {
|
||||
ssr: false
|
||||
});
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
position: 'relative',
|
||||
@@ -138,31 +140,39 @@ const styles = theme => ({
|
||||
|
||||
class Index extends React.Component {
|
||||
state = {
|
||||
emphasisAds: [],
|
||||
emphasisJobs: [],
|
||||
emphasisCompanies: []
|
||||
}
|
||||
componentDidMount() {
|
||||
localStorage.setItem("loginRedirect", "/")
|
||||
this.props.fetchEmphasisAdsRequest({ isEmphasis: 1 })
|
||||
this.props.fetchEmphasisJobsRequest({ isEmphasis: 1 })
|
||||
this.props.fetchEmphasisCompaniesRequest({ isEmphasis: 1 })
|
||||
}
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
this.setState({
|
||||
emphasisAds: nextProps.emphasisAds,
|
||||
emphasisJobs: nextProps.emphasisJobs,
|
||||
emphasisCompanies: nextProps.emphasisCompanies
|
||||
})
|
||||
}
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
const socialShareUrl = typeof window !== 'undefined' ? window.location
|
||||
: publicRuntimeConfig.frontServerUrl ;
|
||||
const DefaultUrl = publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg"
|
||||
const imgUrl = DefaultUrl
|
||||
return (
|
||||
<Layout>
|
||||
<Head>
|
||||
<title key="title"> Talents tube - La recherche d'emploi en vidéo</title>
|
||||
<meta name="description" content="Talents Tube est la première plateforme réservée aux offres d'emploi et aux CV vidéos. Découvrez un nouvelle méthode de recrutement ! Installez notre application." />
|
||||
</Head>
|
||||
<OgHead seo_title="Talents Tube : Plateforme de recrutement 100 % vidéo"
|
||||
seo_description="Talents Tube est la première plateforme réservée aux offres d'emploi vidéo, vidéo marque employeur et aux CV vidéos. Découvrez une nouvelle méthode de recrutement."
|
||||
seo_url={socialShareUrl}
|
||||
image={imgUrl}
|
||||
seo_key="Recrutement, video"
|
||||
|
||||
></OgHead>
|
||||
<div className={classes.container}>
|
||||
|
||||
<VideoSlider />
|
||||
{/* <VideoSlider /> */}
|
||||
|
||||
<section className={classes.scrollerSection + ' ' + classes.scrollerSectionOffer}>
|
||||
<div
|
||||
@@ -179,11 +189,11 @@ class Index extends React.Component {
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
{this.state.emphasisAds.loading ?
|
||||
{this.state.emphasisJobs.loading ?
|
||||
(<Loader />)
|
||||
: !isEmpty(this.state.emphasisAds.data) ? (
|
||||
: !isEmpty(this.state.emphasisJobs.data) ? (
|
||||
<HorizontalScroller
|
||||
data={this.state.emphasisAds.data}
|
||||
data={this.state.emphasisJobs.data}
|
||||
className={classes.HorizontalScroller}
|
||||
type="offre"
|
||||
>
|
||||
@@ -253,7 +263,7 @@ class Index extends React.Component {
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
emphasisAds: state.emphasisAds,
|
||||
emphasisJobs: state.emphasisJobs,
|
||||
emphasisCompanies: state.emphasisCompanies
|
||||
};
|
||||
}
|
||||
@@ -262,4 +272,4 @@ Index.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default (connect(mapStateToProps, { fetchEmphasisAdsRequest, fetchEmphasisCompaniesRequest })(withStyles(styles)(Index)));
|
||||
export default (connect(mapStateToProps, { fetchEmphasisJobsRequest, fetchEmphasisCompaniesRequest })(withStyles(styles)(Index)));
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import Layout from "../components/templates/Layout";
|
||||
import AccountProfile from "../components/organisms/AccountProfile";
|
||||
import AccountVideoPres from "../components/organisms/AccountVideoPres";
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
padding: theme.spacing(4)
|
||||
}
|
||||
}));
|
||||
|
||||
const Account = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className={classes.root}>
|
||||
<Grid
|
||||
container
|
||||
spacing={4}
|
||||
direction="row"
|
||||
justify="space-between"
|
||||
alignItems="flex-start"
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
lg={4}
|
||||
md={6}
|
||||
xl={4}
|
||||
xs={12}
|
||||
>
|
||||
<AccountProfile />
|
||||
<div><br/></div>
|
||||
<AccountVideoPres />
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
lg={8}
|
||||
md={6}
|
||||
xl={8}
|
||||
xs={12}
|
||||
>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Account;
|
||||
@@ -0,0 +1,79 @@
|
||||
import React from 'react';
|
||||
import {makeStyles} from '@material-ui/core/styles';
|
||||
import Layout from "../components/templates/Layout";
|
||||
import AccountProfile from "../components/organisms/AccountProfile";
|
||||
import { Typography } from '@material-ui/core';
|
||||
import Head from 'next/head'
|
||||
import AdBlockDetect from 'react-ad-block-detect';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
width: '100%'
|
||||
},
|
||||
button: {
|
||||
marginRight: theme.spacing(1)
|
||||
},
|
||||
completed: {
|
||||
display: 'inline-block'
|
||||
},
|
||||
instructions: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
information: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: "#fff",
|
||||
fontWeight: '700',
|
||||
fontSize: '1.15em',
|
||||
fontFamily: 'Roboto',
|
||||
[
|
||||
theme
|
||||
.breakpoints
|
||||
.up('md')
|
||||
]: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-around',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
padding: theme.spacing(2, 2)
|
||||
},
|
||||
'& a': {
|
||||
textDecoration: 'none'
|
||||
},
|
||||
texteBlanc: {
|
||||
color: "#fff",
|
||||
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default function HorizontalNonLinearStepper() {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Head>
|
||||
<title key="title">Profile – Talents Tube</title>
|
||||
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
|
||||
</Head>
|
||||
<div >
|
||||
|
||||
<AdBlockDetect >
|
||||
<div className={classes.information}>
|
||||
|
||||
<p>AdBlocks a été détecté. Pour que Talents Tube puisse fonctionner
|
||||
correctement, veuillez désactiver Ad Blocks</p>
|
||||
|
||||
</div>
|
||||
</AdBlockDetect>
|
||||
</div>
|
||||
<div >
|
||||
<AccountProfile/>
|
||||
</div>
|
||||
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "Talents Tube",
|
||||
"short_name": "Talents Tube",
|
||||
"lang": "fr",
|
||||
"orientation":"portrait",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco16x16.png",
|
||||
"sizes": "16x16",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco32x32.png",
|
||||
"sizes": "32x32",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco57x57.png",
|
||||
"sizes": "57x57",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco114x114.png",
|
||||
"sizes": "114x114",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco180x180.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#1689FB",
|
||||
"theme_color": "#1689FB",
|
||||
"gcm_sender_id":"103953800507"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="73.762" height="69.644" viewBox="0 0 73.762 69.644">
|
||||
<g id="Import" transform="translate(0 13.219)">
|
||||
<g id="Groupe_7895" data-name="Groupe 7895" transform="translate(53.502 2.911) rotate(131)">
|
||||
<rect id="Rectangle_316" data-name="Rectangle 316" width="37.465" height="23.87" transform="translate(0.976 1.838)"/>
|
||||
<rect id="Rectangle_321" data-name="Rectangle 321" width="4.656" height="4.656" transform="translate(2.783 18.724)" fill="#fff"/>
|
||||
<rect id="Rectangle_398" data-name="Rectangle 398" width="1.656" height="12.656" transform="translate(2.781 4.725)" fill="#fff"/>
|
||||
<rect id="Rectangle_399" data-name="Rectangle 399" width="1.656" height="8.656" transform="translate(5.781 8.725)" fill="#fff"/>
|
||||
<rect id="Rectangle_400" data-name="Rectangle 400" width="1.656" height="18.656" transform="translate(10.781 4.725)" fill="#fff"/>
|
||||
<path id="Tracé_396" data-name="Tracé 396" d="M0-3H1.656V8.656H0Z" transform="translate(13.781 14.724)" fill="#fff"/>
|
||||
<rect id="Rectangle_401" data-name="Rectangle 401" width="1.656" height="18.656" transform="translate(17.781 4.725)" fill="#fff"/>
|
||||
<path id="Tracé_397" data-name="Tracé 397" d="M0-3H1.656V15.656H0Z" transform="translate(20.781 7.725)" fill="#fff"/>
|
||||
<path id="Tracé_398" data-name="Tracé 398" d="M0-3H1.656V10.788H0Z" transform="translate(23.781 12.593)" fill="#fff"/>
|
||||
<rect id="Rectangle_402" data-name="Rectangle 402" width="1.656" height="18.656" transform="translate(27.781 4.725)" fill="#fff"/>
|
||||
<path id="Tracé_399" data-name="Tracé 399" d="M0,9H1.656v6.656H0Z" transform="translate(33.781 7.725)" fill="#fff"/>
|
||||
<path id="Tracé_400" data-name="Tracé 400" d="M0-3H1.656V10.788H0Z" transform="translate(30.781 12.593)" fill="#fff"/>
|
||||
</g>
|
||||
<path id="Tracé_279" data-name="Tracé 279" d="M217.367,282.859l-6.93,6.93-48.507-6.93L155,275.93l6.93-6.93h55.437Z" transform="translate(-155 -233.363)" fill="#155ee4"/>
|
||||
<path id="Tracé_280" data-name="Tracé 280" d="M173,269v6.93h48.507l6.93-6.93Z" transform="translate(-166.07 -233.363)" opacity="0.25"/>
|
||||
<g id="Groupe_7897" data-name="Groupe 7897" transform="translate(28.442 19.099)">
|
||||
<g id="Groupe_7896" data-name="Groupe 7896" transform="translate(3.551)">
|
||||
<path id="Tracé_281" data-name="Tracé 281" d="M239.065,257.45a.488.488,0,0,1-.231-.039.939.939,0,0,1-.693-1.155,50.925,50.925,0,0,0,1.463-12.088,51.857,51.857,0,0,0-.346-6.006.969.969,0,1,1,1.925-.231,55.915,55.915,0,0,1,.346,6.237,52.807,52.807,0,0,1-1.5,12.55A.952.952,0,0,1,239.065,257.45Z" transform="translate(-238.104 -232.827)" fill="#25d89a"/>
|
||||
<path id="Tracé_282" data-name="Tracé 282" d="M240.5,229.337a1.021,1.021,0,0,1-.962-.808c-.077-.462-.154-.885-.27-1.347a.944.944,0,0,1,1.848-.385c.077.462.192.924.269,1.386a.969.969,0,0,1-.77,1.116A.141.141,0,0,1,240.5,229.337Z" transform="translate(-238.804 -226.042)" fill="#25d89a"/>
|
||||
</g>
|
||||
<path id="Tracé_283" data-name="Tracé 283" d="M233.084,279.525l-4.042-6.237a.972.972,0,1,1,1.617-1.078l3,4.62,4.62-3a.972.972,0,0,1,1.078,1.617Z" transform="translate(-228.879 -254.171)" fill="#25d89a"/>
|
||||
</g>
|
||||
<path id="Tracé_284" data-name="Tracé 284" d="M316.393,300.545h-9.008a.385.385,0,1,1,0-.77h8.7l5.505-5.659a.381.381,0,1,1,.539.539Z" transform="translate(-248.483 -248.739)" fill="#25d89a"/>
|
||||
<path id="Tracé_285" data-name="Tracé 285" d="M317.93,299.2h-6.545a.385.385,0,0,1,0-.77h6.237l4.2-4.312a.381.381,0,1,1,.539.539Z" transform="translate(-250.943 -248.739)" fill="#fa6362"/>
|
||||
<g id="Groupe_7899" data-name="Groupe 7899" transform="translate(30.144 40.641)">
|
||||
<g id="Groupe_7898" data-name="Groupe 7898" transform="translate(0 0)">
|
||||
<path id="Tracé_286" data-name="Tracé 286" d="M233.3,282l2.5,3.811,5.89-3.811h-3.542l-.654.423a1.636,1.636,0,0,0,.077-.423H233.3Z" transform="translate(-233.3 -282)" fill="#21b77e"/>
|
||||
</g>
|
||||
</g>
|
||||
<rect id="Rectangle_325" data-name="Rectangle 325" width="55.437" height="13.859" transform="translate(0 42.566)" fill="#1689fb"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="73.762" height="56.426" viewBox="0 0 73.762 56.426"><defs><style>.a{fill:#fff;}.b{fill:#155ee4;}.c{opacity:0.25;}.d{fill:#25d89a;}.e{fill:#fa6362;}.f{fill:#21b77e;}.g{fill:#1689fb;}</style></defs><g transform="translate(0 0)"><g transform="translate(9.499)"><rect width="42.463" height="23.869" transform="translate(0 3.769) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(1.401 6.158) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(1.866 11.472) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(2.327 16.747) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(2.826 22.019) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(38.67 2.848) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(39.131 8.123) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(39.633 13.433) rotate(-5.093)"/><rect class="a" width="2.656" height="2.656" transform="translate(40.094 18.708) rotate(-5.093)"/><path class="a" d="M229.4,202.9l6.275,3.311-5.582,4.35Z" transform="translate(-210.257 -192.71)"/></g><path class="b" d="M217.367,282.859l-6.93,6.93-48.507-6.93L155,275.93l6.93-6.93h55.437Z" transform="translate(-155 -233.363)"/><path class="c" d="M173,269v6.93h48.507l6.93-6.93Z" transform="translate(-166.07 -233.363)"/><g transform="translate(28.442 19.099)"><g transform="translate(3.551)"><path class="d" d="M239.065,257.45a.488.488,0,0,1-.231-.039.939.939,0,0,1-.693-1.155,50.925,50.925,0,0,0,1.463-12.088,51.857,51.857,0,0,0-.346-6.006.969.969,0,0,1,1.925-.231,55.915,55.915,0,0,1,.346,6.237,52.807,52.807,0,0,1-1.5,12.55A.952.952,0,0,1,239.065,257.45Z" transform="translate(-238.104 -232.827)"/><path class="d" d="M240.5,229.337a1.021,1.021,0,0,1-.962-.808c-.077-.462-.154-.885-.27-1.347a.944.944,0,0,1,1.848-.385c.077.462.192.924.269,1.386a.969.969,0,0,1-.77,1.116A.141.141,0,0,1,240.5,229.337Z" transform="translate(-238.804 -226.042)"/></g><path class="d" d="M233.084,279.525l-4.042-6.237a.972.972,0,1,1,1.617-1.078l3,4.62,4.62-3a.972.972,0,0,1,1.078,1.617Z" transform="translate(-228.879 -254.171)"/></g><path class="d" d="M316.393,300.545h-9.008a.385.385,0,1,1,0-.77h8.7l5.505-5.659a.381.381,0,1,1,.539.539Z" transform="translate(-248.483 -248.739)"/><path class="e" d="M317.93,299.2h-6.545a.385.385,0,0,1,0-.77h6.237l4.2-4.312a.381.381,0,1,1,.539.539Z" transform="translate(-250.943 -248.739)"/><g transform="translate(30.144 40.641)"><g transform="translate(0 0)"><path class="f" d="M233.3,282l2.5,3.811,5.89-3.811h-3.542l-.654.423a1.636,1.636,0,0,0,.077-.423H233.3Z" transform="translate(-233.3 -282)"/></g></g><rect class="g" width="55.437" height="13.859" transform="translate(0 42.566)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="65.694" height="55" viewBox="0 0 65.694 55"><defs><style>.a{fill:#fff;}.b{fill:#fa6362;}.c{fill:#25d89a;}.d{fill:#d0e7fe;}.e{fill:#f8fcff;}</style></defs><g transform="translate(6.99 12.604)"><rect class="a" width="0.382" height="6.302" transform="translate(8.135)"/><rect class="b" width="0.382" height="6.302" transform="translate(8.25 10.503)"/><rect class="b" width="6.302" height="0.382" transform="translate(0 8.288)"/><rect class="a" width="6.302" height="0.382" transform="translate(10.503 8.135)"/><rect class="a" width="0.382" height="4.125" transform="translate(4.324 4.686) rotate(-45)"/><rect class="a" width="0.382" height="4.125" transform="translate(9.254 9.481) rotate(-45)"/><rect class="b" width="4.125" height="0.382" transform="translate(4.392 12.164) rotate(-45)"/><rect class="a" width="4.125" height="0.382" transform="translate(9.186 7.288) rotate(-45)"/></g><path class="c" d="M249.806,254.569H236.819A3.831,3.831,0,0,1,233,250.75v-9.931A3.831,3.831,0,0,1,236.819,237h12.986a3.831,3.831,0,0,1,3.819,3.819v9.931A3.831,3.831,0,0,1,249.806,254.569Z" transform="translate(-206.646 -214.465)"/><path class="d" d="M235.875,281.75,229,288.625l-48.125-6.875L174,274.875,180.875,268h55Z" transform="translate(-170.181 -233.625)"/><rect class="a" width="55" height="13.75" transform="translate(3.819 41.25)"/><path class="d" d="M185.58,296.5h-9.549a3.748,3.748,0,0,1-2.483-.917c-.8-.687.382-8.441.382-9.587H189.4v6.684A3.831,3.831,0,0,1,185.58,296.5Z" transform="translate(-169.73 -244.75)"/><path d="M177.368,258.556h-9.549A3.831,3.831,0,0,1,164,254.736V231.819A3.831,3.831,0,0,1,167.819,228h9.549a3.831,3.831,0,0,1,3.819,3.819v22.917A3.831,3.831,0,0,1,177.368,258.556Z" transform="translate(-164 -208.903)"/><path class="a" d="M178.533,259.028h-9.778c-2.1,0-3.056-1.719-3.056-3.819V233.819c0-2.1.955-3.819,3.056-3.819h9.778c2.1,0,3.056,1.719,3.056,3.819v21.389C181.589,257.309,180.634,259.028,178.533,259.028Z" transform="translate(-165.051 -210.139)"/><circle class="c" cx="6.875" cy="6.875" r="6.875" transform="translate(29.792 6.875)"/><path class="c" d="M180.042,279h-1.3A3.749,3.749,0,0,1,175,275.254v-6.111a3.749,3.749,0,0,1,3.743-3.743h1.3a3.749,3.749,0,0,1,3.743,3.743v6.111A3.749,3.749,0,0,1,180.042,279Z" transform="translate(-170.799 -232.018)"/><circle class="c" cx="2.941" cy="2.941" r="2.941" transform="translate(5.653 26.736)"/><path d="M181.589,282.1v5.309c0,2.1-.955,3.819-3.056,3.819h-9.778c-2.1,0-3.056-1.719-3.056-3.819V282.1Z" transform="translate(-165.051 -242.34)"/><circle class="a" cx="1.91" cy="1.91" r="1.91" transform="translate(6.875 42.396)"/><circle class="b" cx="1.26" cy="1.26" r="1.26" transform="translate(7.524 43.045)"/><g transform="translate(48.15)"><path class="e" d="M303.981,180.368a8.149,8.149,0,0,0-12.069,10.924,3.012,3.012,0,0,1-1.3,1.49.77.77,0,0,0,.229,1.451,2.89,2.89,0,0,0,.573.038h0a5.282,5.282,0,0,0,2.941-.955,8.018,8.018,0,0,0,3.858.955,8.183,8.183,0,0,0,5.767-2.368,7.961,7.961,0,0,0,2.368-5.767A8.183,8.183,0,0,0,303.981,180.368Zm-.649,10.885a7.129,7.129,0,0,1-5.118,2.1,7.236,7.236,0,0,1-3.667-.993.543.543,0,0,0-.229-.076.552.552,0,0,0-.267.076,4.7,4.7,0,0,1-2.559.955,4.748,4.748,0,0,0,1.375-1.91.48.48,0,0,0-.076-.5,7.219,7.219,0,0,1,.306-9.892,7.129,7.129,0,0,1,5.118-2.1,7.219,7.219,0,0,1,5.118,12.337Z" transform="translate(-290.064 -178)"/><path class="e" d="M308.557,192.3h-6.8a.458.458,0,1,0,0,.917h6.8a.458.458,0,1,0,0-.917Z" transform="translate(-297.009 -186.838)"/><path class="e" d="M308.557,198.1h-6.8a.458.458,0,1,0,0,.917h6.8a.458.458,0,1,0,0-.917Z" transform="translate(-297.009 -190.423)"/><path class="e" d="M306.265,203.9h-4.507a.458.458,0,1,0,0,.917h4.507a.441.441,0,0,0,.458-.458A.464.464,0,0,0,306.265,203.9Z" transform="translate(-297.009 -194.008)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,12 @@
|
||||
<svg id="Groupe_8099" data-name="Groupe 8099" xmlns="http://www.w3.org/2000/svg" width="65.497" height="40.618" viewBox="0 0 65.497 40.618">
|
||||
<path id="Tracé_401" data-name="Tracé 401" d="M0,0H62.62V35.2H0Z" transform="translate(0 5.559) rotate(-5.093)"/>
|
||||
<rect id="Rectangle_317" data-name="Rectangle 317" width="3.917" height="3.917" transform="translate(2.066 9.081) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_318" data-name="Rectangle 318" width="3.917" height="3.917" transform="translate(2.751 16.917) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_319" data-name="Rectangle 319" width="3.917" height="3.917" transform="translate(3.431 24.696) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_320" data-name="Rectangle 320" width="3.917" height="3.917" transform="translate(4.167 32.47) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_321" data-name="Rectangle 321" width="3.917" height="3.917" transform="translate(57.023 4.199) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_322" data-name="Rectangle 322" width="3.917" height="3.917" transform="translate(57.703 11.978) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_323" data-name="Rectangle 323" width="3.917" height="3.917" transform="translate(58.444 19.809) rotate(-5.093)" fill="#fff"/>
|
||||
<rect id="Rectangle_324" data-name="Rectangle 324" width="3.917" height="3.917" transform="translate(59.124 27.588) rotate(-5.093)" fill="#fff"/>
|
||||
<text id="_" data-name="?" transform="matrix(0.996, -0.087, 0.087, 0.996, 26.298, 31.189)" fill="#fff" font-size="29" font-family="Roboto-Bold, Roboto" font-weight="700"><tspan x="0" y="0">?</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 400 400" style="enable-background:new 0 0 400 400;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#F3F9FF;}
|
||||
.st1{fill:#1689FB;}
|
||||
</style>
|
||||
<g>
|
||||
<circle class="st0" cx="200.32" cy="200.12" r="194.12"/>
|
||||
<circle class="st1" cx="200.32" cy="144.75" r="69.37"/>
|
||||
<path class="st1" d="M265.84,233.39H134.8c-21.2,0-38.54,17.34-38.54,38.54v92.09c30.08,19.14,65.77,30.22,104.06,30.22
|
||||
s73.98-11.09,104.06-30.22v-92.09C304.38,250.73,287.04,233.39,265.84,233.39z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 755 B |
@@ -0,0 +1,42 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1920" height="1080" viewBox="0 0 1920 1080">
|
||||
<defs>
|
||||
<radialGradient id="radial-gradient" cx="0.403" cy="0.395" r="1.057" gradientTransform="translate(0.146 -0.002) scale(0.637 1.004)" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#155ee4"/>
|
||||
<stop offset="1" stop-color="#8dc6ff"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="radial-gradient-2" cx="0.319" cy="0.609" r="1.639" gradientTransform="matrix(0.358, 0.411, -0.161, 0.912, 0.303, -0.077)" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#1689fb"/>
|
||||
<stop offset="1" stop-color="#54d7e6"/>
|
||||
</radialGradient>
|
||||
<filter id="Tracé_105" x="781.117" y="346.457" width="822.06" height="723.468" filterUnits="userSpaceOnUse">
|
||||
<feOffset dy="-27" input="SourceAlpha"/>
|
||||
<feGaussianBlur stdDeviation="43" result="blur"/>
|
||||
<feFlood flood-opacity="0.161"/>
|
||||
<feComposite operator="in" in2="blur"/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
<radialGradient id="radial-gradient-3" cx="0.524" cy="0.704" r="0.76" gradientTransform="matrix(-0.323, -0.938, 0.872, -0.347, 0.079, 1.439)" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#1689fb" stop-opacity="0.6"/>
|
||||
<stop offset="1" stop-color="#54d7e6" stop-opacity="0.6"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="radial-gradient-4" cx="0.447" cy="0.416" r="1.057" gradientTransform="translate(0.162 -0.002) scale(0.637 1.004)" xlink:href="#radial-gradient-2"/>
|
||||
<radialGradient id="radial-gradient-5" cx="0.915" cy="0.609" r="1.568" gradientTransform="matrix(0.184, 0.259, -0.081, 1.582, 0.795, -0.591)" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#fff" stop-opacity="0.475"/>
|
||||
<stop offset="1" stop-color="#fff" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip-Youtube_4">
|
||||
<rect width="1920" height="1080"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="Youtube_4" data-name="Youtube – 4" clip-path="url(#clip-Youtube_4)">
|
||||
<rect width="1920" height="1080" fill="#fff"/>
|
||||
<path id="Tracé_106" data-name="Tracé 106" d="M12369.043,2300.3s-141.664-1034.519,765.283-1034.519c214.947,0,511.67,196.543,697.428,58.283,408.648-304.154,352.379-1089.441,934.215-1425.363,574.066-331.437,1213.727-72.058,1566.926,55.155s-251.332,2385.215-251.332,2385.215" transform="translate(-14153.795 -949.145)" fill="url(#radial-gradient)"/>
|
||||
<path id="Tracé_101" data-name="Tracé 101" d="M11762.942,398.383s55.409-341.747,332.711-280.328,290.146,146.232,543.427,0,251.155-350.119,595.736-131.889,887.4,587.9,856.8,724.362-2328.67,85.529-2328.67,85.529Z" transform="translate(-11803 322)" fill="url(#radial-gradient-2)"/>
|
||||
<g transform="matrix(1, 0, 0, 1, 0, 0)" filter="url(#Tracé_105)">
|
||||
<path id="Tracé_105-2" data-name="Tracé 105" d="M12760.129,408.192c118.317,8.328,220.3,90.749,319.038-145.828s198.01,114.584,198.01,114.584l-493.051,268.977S12641.812,399.864,12760.129,408.192Z" transform="translate(-11803 322)" fill="#fff"/>
|
||||
</g>
|
||||
<path id="Tracé_102" data-name="Tracé 102" d="M534.949,72.539C818.824,72.539,1028,230.126,1028,514s-230.126,514-514,514S0,797.874,0,514,251.075,72.539,534.949,72.539Z" transform="translate(-200 201)" fill="url(#radial-gradient-3)"/>
|
||||
<path id="Tracé_103" data-name="Tracé 103" d="M12364.285,780.991s-57.706-421.407,311.735-421.407c87.558,0,208.426,80.061,284.094,23.741,166.461-123.9,143.54-443.779,380.548-580.615,233.844-135.01,494.406-29.353,638.281,22.467s-102.379,971.607-102.379,971.607" transform="translate(-11803 322)" fill="url(#radial-gradient-4)"/>
|
||||
<path id="Tracé_107" data-name="Tracé 107" d="M11779.612,537.613s427.922-55.028,1287.072,146.785,1121.613,162.176,1983.9-332.047,198.711,587.6,198.711,587.6L11739.1,909.484Z" transform="translate(-12748.872 179.263)" fill="url(#radial-gradient-5)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="277.043" height="328" viewBox="0 0 277.043 328">
|
||||
<g id="Groupe_7859" data-name="Groupe 7859" transform="translate(-4.489 -11.849)">
|
||||
<circle id="Ellipse_105" data-name="Ellipse 105" cx="40.594" cy="40.594" r="40.594" transform="translate(119.489 270.847) rotate(-90.438)"/>
|
||||
<circle id="Ellipse_106" data-name="Ellipse 106" cx="40.594" cy="40.594" r="40.594" transform="translate(119.554 163.329) rotate(-90.438)"/>
|
||||
<circle id="Ellipse_107" data-name="Ellipse 107" cx="48.799" cy="48.799" r="48.799" transform="translate(5.344 225.063) rotate(-90.438)"/>
|
||||
<circle id="Ellipse_108" data-name="Ellipse 108" cx="48.799" cy="48.799" r="48.799" transform="matrix(-0.008, -1, 1, -0.008, 5.253, 110.195)"/>
|
||||
<circle id="Ellipse_109" data-name="Ellipse 109" cx="48.799" cy="48.799" r="48.799" transform="translate(5.235 339.849) rotate(-90.438)"/>
|
||||
<circle id="Ellipse_110" data-name="Ellipse 110" cx="33.901" cy="33.901" r="33.901" transform="translate(213.73 210.028) rotate(-90.438)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 370 B |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 709 B |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,144 @@
|
||||
///
|
||||
/// Thomas Berrod
|
||||
/// A generic service worker
|
||||
/// inspired by https://github.com/gauntface/web-push-book
|
||||
///
|
||||
|
||||
; (function () {
|
||||
"use strict";
|
||||
|
||||
self.importScripts('/static/js/analytics-helper.js');
|
||||
|
||||
function focusWindow(event) {
|
||||
const url = event.notification.data["link"]; //TODO : there are 2 web server now...
|
||||
const urlToOpen = new URL(url, self.location.origin).href;
|
||||
|
||||
const promiseChain = clients.matchAll({
|
||||
type: 'window',
|
||||
includeUncontrolled: true
|
||||
})
|
||||
.then((windowClients) => {
|
||||
let matchingClient = null;
|
||||
|
||||
for (let i = 0; i < windowClients.length; i++) {
|
||||
const windowClient = windowClients[i];
|
||||
if (windowClient.url === urlToOpen) {
|
||||
matchingClient = windowClient;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matchingClient) {
|
||||
return matchingClient.focus();
|
||||
} else {
|
||||
return clients.openWindow(urlToOpen);
|
||||
}
|
||||
});
|
||||
event.waitUntil(promiseChain);
|
||||
}
|
||||
|
||||
function isClientFocused() {
|
||||
return clients.matchAll({
|
||||
type: 'window',
|
||||
includeUncontrolled: true
|
||||
})
|
||||
.then((windowClients) => {
|
||||
let clientIsFocused = false;
|
||||
|
||||
for (let i = 0; i < windowClients.length; i++) {
|
||||
const windowClient = windowClients[i];
|
||||
if (windowClient.focused) {
|
||||
clientIsFocused = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return clientIsFocused;
|
||||
});
|
||||
}
|
||||
|
||||
function demoMustShowNotificationCheck(event) {
|
||||
const promiseChain = isClientFocused()
|
||||
.then((clientIsFocused) => {
|
||||
if (clientIsFocused) {
|
||||
|
||||
//could alert
|
||||
demoSendMessageToPage(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// Client isn't focused, we need to show a notification.
|
||||
return self.registration.showNotification(
|
||||
event.data.json().notification.title,
|
||||
event.data.json().notification);
|
||||
});
|
||||
|
||||
event.waitUntil(promiseChain);
|
||||
}
|
||||
|
||||
function demoSendMessageToPage(event) {
|
||||
|
||||
const promiseChain = isClientFocused()
|
||||
.then((clientIsFocused) => {
|
||||
if (clientIsFocused) {
|
||||
clients.matchAll({
|
||||
type: 'window',
|
||||
includeUncontrolled: true
|
||||
}).then((windowClients) => {
|
||||
let clientIsFocused = false;
|
||||
|
||||
for (let i = 0; i < windowClients.length; i++) {
|
||||
const windowClient = windowClients[i];
|
||||
if (windowClient.focused) {
|
||||
console.info('Posting message to page');
|
||||
windowClient.postMessage(event.data.json().notification);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return self.registration.showNotification('No focused windows', {
|
||||
body: 'Had to show a notification instead of messaging each page.'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
event.waitUntil(promiseChain);
|
||||
}
|
||||
|
||||
self.addEventListener('push', function (event) {
|
||||
|
||||
demoMustShowNotificationCheck(event);
|
||||
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', function (event) {
|
||||
event.waitUntil(
|
||||
sendAnalyticsEvent('click', 'Push', event.notification.title)
|
||||
);
|
||||
|
||||
event.notification.close();
|
||||
switch (event.notification.tag) {
|
||||
case 'open-window':
|
||||
focusWindow(event);
|
||||
break;
|
||||
default:
|
||||
//
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
const notificationCloseAnalytics = () => {
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
self.addEventListener('notificationclose', function (event) {
|
||||
const dismissedNotification = event.notification;
|
||||
event.waitUntil(
|
||||
sendAnalyticsEvent('close', 'Push', event.notification.title)
|
||||
);
|
||||
const promiseChain = notificationCloseAnalytics();
|
||||
event.waitUntil(promiseChain);
|
||||
});
|
||||
|
||||
})()
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// INFO : this file is required to track push event inside the serviceworker
|
||||
//
|
||||
|
||||
// Set this to your tracking ID
|
||||
var trackingId = 'UA-98246968-6';
|
||||
|
||||
function sendAnalyticsEvent(eventAction, eventCategory, eventLabel) {
|
||||
'use strict';
|
||||
|
||||
console.info('Sending analytics event: ' + eventCategory + '/' + eventAction);
|
||||
|
||||
if (!trackingId) {
|
||||
console.error('You need your tracking ID in analytics-helper.js');
|
||||
console.error('Add this code:\nvar trackingId = \'UA-XXXXXXXX-X\';');
|
||||
// We want this to be a safe method, so avoid throwing unless absolutely necessary.
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!eventAction && !eventCategory && !eventLabel) {
|
||||
console.warn('sendAnalyticsEvent() called with no eventAction or ' +
|
||||
'eventCategory or '+
|
||||
'eventLabel');
|
||||
// We want this to be a safe method, so avoid throwing unless absolutely necessary.
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return self.registration.pushManager.getSubscription()
|
||||
.then(function(subscription) {
|
||||
if (subscription === null) {
|
||||
throw new Error('No subscription currently available.');
|
||||
}
|
||||
|
||||
// Create hit data
|
||||
var payloadData = {
|
||||
// Version Number
|
||||
v: 1,
|
||||
// Client ID
|
||||
cid: subscription.endpoint,
|
||||
// Tracking ID
|
||||
tid: trackingId,
|
||||
// Hit Type
|
||||
t: 'event',
|
||||
// Event Category
|
||||
ec: eventCategory,
|
||||
// Event Action
|
||||
ea: eventAction,
|
||||
// Event Label
|
||||
el: eventLabel
|
||||
};
|
||||
|
||||
// Format hit data into URI
|
||||
var payloadString = Object.keys(payloadData)
|
||||
.filter(function(analyticsKey) {
|
||||
return payloadData[analyticsKey];
|
||||
})
|
||||
.map(function(analyticsKey) {
|
||||
return analyticsKey + '=' + encodeURIComponent(payloadData[analyticsKey]);
|
||||
})
|
||||
.join('&');
|
||||
|
||||
// Post to Google Analytics endpoint
|
||||
return fetch('https://www.google-analytics.com/collect', {
|
||||
method: 'post',
|
||||
body: payloadString
|
||||
});
|
||||
})
|
||||
.then(function(response) {
|
||||
if (!response.ok) {
|
||||
return response.text()
|
||||
.then(function(responseText) {
|
||||
throw new Error(
|
||||
'Bad response from Google Analytics:\n' + response.status
|
||||
);
|
||||
});
|
||||
} else {
|
||||
console.info(eventCategory + '/' + eventAction +
|
||||
'hit sent, check the Analytics dashboard');
|
||||
}
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.warn('Unable to send the analytics event', err);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2018 Google Inc.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.5.0/workbox-sw.js');
|
||||
|
||||
if (workbox) {
|
||||
console.info(`Yay! Workbox from backgroundSync-sw.js is loaded 🎉`);
|
||||
workbox.precaching.precacheAndRoute([]);
|
||||
|
||||
// const showNotification = (z) => {
|
||||
// console.log(z);
|
||||
// self.registration.showNotification('🔄 Votre message a été envoyé !', {
|
||||
// body: '🎉`🎉`🎉`'
|
||||
// });
|
||||
// };
|
||||
|
||||
const bgSyncPlugin = new workbox.backgroundSync.Plugin(
|
||||
'dashboardr-queue'
|
||||
);
|
||||
|
||||
const networkWithBackgroundSync = new workbox.strategies.NetworkOnly({
|
||||
plugins: [bgSyncPlugin],
|
||||
});
|
||||
|
||||
workbox.routing.registerRoute(
|
||||
/\/feedback/,
|
||||
networkWithBackgroundSync,
|
||||
'POST'
|
||||
);
|
||||
|
||||
} else {
|
||||
console.info(`Boo! Workbox from backgroundSync-sw.js didn't load 😬`);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
function promptInstall() {
|
||||
if (deferredPrompt == null) {
|
||||
console.info('beforeinstallprompt has not been triggerred yet');
|
||||
return;
|
||||
}
|
||||
// never show it if the app was launched standalone
|
||||
if (navigator.standalone) {
|
||||
return;
|
||||
}
|
||||
// Show the prompt
|
||||
deferredPrompt.prompt();
|
||||
// Wait for the user to respond to the prompt
|
||||
deferredPrompt.userChoice
|
||||
.then((choiceResult) => {
|
||||
if (choiceResult.outcome === 'accepted') {
|
||||
console.info('User accepted the A2HS prompt');
|
||||
} else {
|
||||
console.info('User dismissed the A2HS prompt');
|
||||
}
|
||||
deferredPrompt = null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var deferredPrompt;
|
||||
|
||||
/// cf https://developers.google.com/web/fundamentals/app-install-banners/
|
||||
///
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
// Prevent Chrome 67 and earlier from automatically showing the prompt
|
||||
e.preventDefault();
|
||||
// Stash the event so it can be triggered later.
|
||||
deferredPrompt = e;
|
||||
});
|
||||
|
||||
window.addEventListener('appinstalled', (evt) => {
|
||||
console.info('a2hs installed');
|
||||
});
|
||||
|
||||
const isInStandaloneMode = () =>
|
||||
(window.matchMedia('(display-mode: standalone)').matches) || (window.navigator.standalone);
|
||||
|
||||
console.info('EdeclicLib loaded');
|
||||
|
||||
// window.addEventListener('error', function (e) {
|
||||
// var errorText = [
|
||||
// e.message,
|
||||
// 'URL: ' + e.filename,
|
||||
// 'Line: ' + e.lineno + ', Column: ' + e.colno,
|
||||
// 'Stack: ' + (e.error && e.error.stack || '(no stack trace)')
|
||||
// ].join('');
|
||||
// console.log(errorText);
|
||||
// // Example: log errors as visual output into the host page.
|
||||
// // Note: you probably don’t want to show such errors to users, or
|
||||
// // have the errors get indexed by Googlebot; however, it may
|
||||
// // be a useful feature while actively debugging the page.
|
||||
// var DOM_ID = 'rendering-debug-pre';
|
||||
// if (!document.getElementById(DOM_ID)) {
|
||||
// var log = document.createElement('pre');
|
||||
// log.id = DOM_ID;
|
||||
// log.style.whiteSpace = 'pre-wrap';
|
||||
// log.textContent = errorText;
|
||||
// if (!document.body) document.body = document.createElement('body');
|
||||
// document.body.insertBefore(log, document.body.firstChild);
|
||||
// } else {
|
||||
// document.getElementById(DOM_ID).textContent += ' ' + errorText;
|
||||
// }
|
||||
// });
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "Talents Tube",
|
||||
"short_name": "Talents Tube",
|
||||
"lang": "fr",
|
||||
"orientation":"portrait",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco16x16.png",
|
||||
"sizes": "16x16",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco32x32.png",
|
||||
"sizes": "32x32",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco57x57.png",
|
||||
"sizes": "57x57",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco114x114.png",
|
||||
"sizes": "114x114",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco180x180.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/talentstubeIco512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#1689FB",
|
||||
"theme_color": "#1689FB",
|
||||
"gcm_sender_id":"103953800507"
|
||||
}
|
||||
@@ -1,26 +1,26 @@
|
||||
import { createSelector } from "reselect";
|
||||
import {
|
||||
FETCH_AD_REQUEST,
|
||||
FETCH_AD_SUCCESS,
|
||||
FETCH_AD_FAILURE,
|
||||
FETCH_JOB_REQUEST,
|
||||
FETCH_JOB_SUCCESS,
|
||||
FETCH_JOB_FAILURE,
|
||||
CLEAR_AD
|
||||
} from "../types";
|
||||
|
||||
export function ad(state = {
|
||||
}, action = {}) {
|
||||
switch (action.type) {
|
||||
case FETCH_AD_REQUEST:
|
||||
case FETCH_JOB_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading:true
|
||||
};
|
||||
case FETCH_AD_SUCCESS:
|
||||
case FETCH_JOB_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
...action.res,
|
||||
loading: false
|
||||
};
|
||||
case FETCH_AD_FAILURE:
|
||||
case FETCH_JOB_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.error,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createSelector } from "reselect";
|
||||
import {
|
||||
FETCH_ADS_SUCCESS,
|
||||
FETCH_ADS_FAILURE,
|
||||
FETCH_ADS_REQUEST,
|
||||
FETCH_JOBS_SUCCESS,
|
||||
FETCH_JOBS_FAILURE,
|
||||
FETCH_JOBS_REQUEST,
|
||||
TOGGLE_PROMOTED_FILTER_ADS,
|
||||
} from "../types";
|
||||
|
||||
@@ -10,18 +10,18 @@ export function ads(state = {
|
||||
}, action = {}) {
|
||||
|
||||
switch (action.type) {
|
||||
case FETCH_ADS_REQUEST:
|
||||
case FETCH_JOBS_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading:true
|
||||
};
|
||||
case FETCH_ADS_SUCCESS:
|
||||
case FETCH_JOBS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
...action.res,
|
||||
loading:false
|
||||
};
|
||||
case FETCH_ADS_FAILURE:
|
||||
case FETCH_JOBS_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.error,
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import { createSelector } from "reselect";
|
||||
import {
|
||||
FETCH_ADS_ANSWER_REQUEST,
|
||||
FETCH_ADS_ANSWER_SUCCESS,
|
||||
FETCH_ADS_ANSWER_FAILURE,
|
||||
FETCH_JOBS_ANSWER_REQUEST,
|
||||
FETCH_JOBS_ANSWER_SUCCESS,
|
||||
FETCH_JOBS_ANSWER_FAILURE,
|
||||
} from "../types";
|
||||
|
||||
export function answers(state = {
|
||||
}, action = {}) {
|
||||
switch (action.type) {
|
||||
case FETCH_ADS_ANSWER_REQUEST:
|
||||
case FETCH_JOBS_ANSWER_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading: true
|
||||
};
|
||||
case FETCH_ADS_ANSWER_SUCCESS:
|
||||
case FETCH_JOBS_ANSWER_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
...action.res,
|
||||
loading: false
|
||||
};
|
||||
case FETCH_ADS_ANSWER_FAILURE:
|
||||
case FETCH_JOBS_ANSWER_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.error,
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import { createSelector } from "reselect";
|
||||
import {
|
||||
FETCH_EMPHASIS_ADS_SUCCESS,
|
||||
FETCH_EMPHASIS_ADS_FAILURE,
|
||||
FETCH_EMPHASIS_ADS_REQUEST,
|
||||
FETCH_EMPHASIS_JOBS_SUCCESS,
|
||||
FETCH_EMPHASIS_JOBS_FAILURE,
|
||||
FETCH_EMPHASIS_JOBS_REQUEST,
|
||||
|
||||
} from "../types";
|
||||
|
||||
export function emphasisAds(state = {
|
||||
export function emphasisJobs(state = {
|
||||
}, action = {}) {
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
case FETCH_EMPHASIS_ADS_REQUEST:
|
||||
case FETCH_EMPHASIS_JOBS_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading:true
|
||||
};
|
||||
case FETCH_EMPHASIS_ADS_SUCCESS:
|
||||
case FETCH_EMPHASIS_JOBS_SUCCESS:
|
||||
return {
|
||||
...action.res,
|
||||
loading:false
|
||||
};
|
||||
case FETCH_EMPHASIS_ADS_FAILURE:
|
||||
case FETCH_EMPHASIS_JOBS_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.error,
|
||||
@@ -34,8 +34,8 @@ export function emphasisAds(state = {
|
||||
}
|
||||
|
||||
|
||||
export const emphasisAdsHashSelector = state => state.emphasisAds.data;
|
||||
export const emphasisJobsHashSelector = state => state.emphasisJobs.data;
|
||||
|
||||
export const emphasisAdsSelector = createSelector(emphasisAdsHashSelector, hash =>
|
||||
export const emphasisJobsSelector = createSelector(emphasisJobsHashSelector, hash =>
|
||||
Object.values(hash)
|
||||
);
|
||||
@@ -2,6 +2,12 @@ import {
|
||||
UPLOAD_MEDIA_REQUEST,
|
||||
UPLOAD_MEDIA_SUCCESS,
|
||||
UPLOAD_MEDIA_FAILURE,
|
||||
UPLOAD_MEDIA_PRES_REQUEST,
|
||||
UPLOAD_MEDIA_PRES_FAILURE,
|
||||
UPLOAD_MEDIA_PRES_SUCCESS,
|
||||
UPLOAD_MEDIA_CV_REQUEST,
|
||||
UPLOAD_MEDIA_CV_FAILURE,
|
||||
UPLOAD_MEDIA_CV_SUCCESS,
|
||||
} from "../types";
|
||||
|
||||
export function media(state = {
|
||||
@@ -24,6 +30,40 @@ export function media(state = {
|
||||
errors: action.errors,
|
||||
loading: false
|
||||
};
|
||||
case UPLOAD_MEDIA_PRES_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading: true
|
||||
};
|
||||
case UPLOAD_MEDIA_PRES_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
...action.res.data,
|
||||
loading: false
|
||||
};
|
||||
case UPLOAD_MEDIA_PRES_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.errors,
|
||||
loading: false
|
||||
};
|
||||
case UPLOAD_MEDIA_CV_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
loading: true
|
||||
};
|
||||
case UPLOAD_MEDIA_CV_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
...action.res.data,
|
||||
loading: false
|
||||
};
|
||||
case UPLOAD_MEDIA_CV_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: action.errors,
|
||||
loading: false
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { combineReducers } from "redux";
|
||||
import { user } from "./reducers/user";
|
||||
import { ad } from "./reducers/ad";
|
||||
import { ads } from "./reducers/ads";
|
||||
import { emphasisAds } from "./reducers/emphasisAds";
|
||||
import { emphasisJobs } from "./reducers/emphasisJobs";
|
||||
import { company } from "./reducers/company";
|
||||
import { companies } from "./reducers/companies";
|
||||
import { emphasisCompanies } from "./reducers/emphasisCompanies";
|
||||
@@ -24,8 +24,8 @@ export const exampleInitialState = {
|
||||
ad: {
|
||||
|
||||
},
|
||||
emphasisAds: {
|
||||
|
||||
emphasisJobs: {
|
||||
|
||||
},
|
||||
companies: {
|
||||
data: {}
|
||||
@@ -50,7 +50,7 @@ export const exampleInitialState = {
|
||||
export default combineReducers({
|
||||
user,
|
||||
ads,
|
||||
emphasisAds,
|
||||
emphasisJobs,
|
||||
ad,
|
||||
companies,
|
||||
company,
|
||||
|
||||
@@ -9,18 +9,18 @@ import {
|
||||
requestRegisterSaga, requestLogoutSaga, requestNewsletterSubscribitionSaga,
|
||||
requestUpdateUserRequestSaga, requestUserSubscriptionToPushSaga
|
||||
} from './sagas/userSaga.js'
|
||||
import { requestAdsSaga, requestAdSaga, requestEmphasisAdsSaga, countAdViewRequestSaga } from './sagas/offreSaga.js'
|
||||
import { requestAdsSaga, requestAdSaga, requestEmphasisJobsSaga, countAdViewRequestSaga } from './sagas/offreSaga.js'
|
||||
import { requestCompaniesSaga, requestCompanySaga, requestEmphasisCompaniesSaga, countCompanyViewRequestSaga } from './sagas/companySaga.js'
|
||||
import { postAnswerMessageSaga, postAdAnswerRequestSaga, uploadMediaSaga, fetchAdsAnsweredRequestSaga, fetchAnswerRequestSaga, fetchAnswerMessagesRequestSaga } from './sagas/answerSaga.js'
|
||||
import { postAnswerMessageSaga, postAdAnswerRequestSaga, uploadMediaSaga, uploadMediaPresSaga, uploadMediaCvSaga, fetchJobsAnsweredRequestSaga, fetchAnswerRequestSaga, fetchAnswerMessagesRequestSaga } from './sagas/answerSaga.js'
|
||||
|
||||
import {
|
||||
REQUEST_LOGIN,
|
||||
REQUEST_LOGOUT,
|
||||
REQUEST_REGISTER,
|
||||
FETCH_CURRENT_USER_REQUEST,
|
||||
FETCH_ADS_REQUEST,
|
||||
FETCH_AD_REQUEST,
|
||||
FETCH_EMPHASIS_ADS_REQUEST,
|
||||
FETCH_JOBS_REQUEST,
|
||||
FETCH_JOB_REQUEST,
|
||||
FETCH_EMPHASIS_JOBS_REQUEST,
|
||||
FETCH_EMPHASIS_COMPANIES_REQUEST,
|
||||
FETCH_COMPANIES_REQUEST,
|
||||
FETCH_COMPANY_REQUEST,
|
||||
@@ -29,8 +29,10 @@ import {
|
||||
ACCOUNT_CONFIRMATION_REQUEST,
|
||||
POST_AD_ANSWER_REQUEST,
|
||||
UPLOAD_MEDIA_REQUEST,
|
||||
UPLOAD_MEDIA_PRES_REQUEST,
|
||||
UPLOAD_MEDIA_CV_REQUEST,
|
||||
UPDATE_USER_REQUEST,
|
||||
FETCH_ADS_ANSWER_REQUEST,
|
||||
FETCH_JOBS_ANSWER_REQUEST,
|
||||
FETCH_ANSWER_REQUEST,
|
||||
VERIFY_USER_REQUEST,
|
||||
RESET_PASSWORD_REQUEST,
|
||||
@@ -55,9 +57,9 @@ function* rootSaga() {
|
||||
takeLatest(FETCH_CURRENT_USER_REQUEST, requestUserSaga),
|
||||
takeLatest(UPDATE_USER_REQUEST, requestUpdateUserSaga),
|
||||
takeLatest(SUBSCRIBE_NEWSLETTER_REQUEST, requestNewsletterSubscribitionSaga),
|
||||
takeLatest(FETCH_ADS_REQUEST, requestAdsSaga),
|
||||
takeLatest(FETCH_AD_REQUEST, requestAdSaga),
|
||||
takeLatest(FETCH_EMPHASIS_ADS_REQUEST, requestEmphasisAdsSaga),
|
||||
takeLatest(FETCH_JOBS_REQUEST, requestAdsSaga),
|
||||
takeLatest(FETCH_JOB_REQUEST, requestAdSaga),
|
||||
takeLatest(FETCH_EMPHASIS_JOBS_REQUEST, requestEmphasisJobsSaga),
|
||||
takeLatest(FETCH_EMPHASIS_COMPANIES_REQUEST, requestEmphasisCompaniesSaga),
|
||||
takeLatest(FETCH_COMPANIES_REQUEST, requestCompaniesSaga),
|
||||
takeLatest(FETCH_COMPANY_REQUEST, requestCompanySaga),
|
||||
@@ -65,7 +67,9 @@ function* rootSaga() {
|
||||
takeLatest(ACCOUNT_CONFIRMATION_REQUEST, requestConfirmationAccountSaga),
|
||||
takeLatest(POST_AD_ANSWER_REQUEST, postAdAnswerRequestSaga),
|
||||
takeLatest(UPLOAD_MEDIA_REQUEST, uploadMediaSaga),
|
||||
takeLatest(FETCH_ADS_ANSWER_REQUEST, fetchAdsAnsweredRequestSaga),
|
||||
takeLatest(UPLOAD_MEDIA_PRES_REQUEST, uploadMediaPresSaga),
|
||||
takeLatest(UPLOAD_MEDIA_CV_REQUEST, uploadMediaCvSaga),
|
||||
takeLatest(FETCH_JOBS_ANSWER_REQUEST, fetchJobsAnsweredRequestSaga),
|
||||
takeLatest(FETCH_ANSWER_REQUEST, fetchAnswerRequestSaga),
|
||||
takeLatest(VERIFY_USER_REQUEST, verifyUserSaga),
|
||||
takeLatest(RESET_PASSWORD_REQUEST, requestResetPasswordSaga),
|
||||
@@ -79,4 +83,4 @@ function* rootSaga() {
|
||||
])
|
||||
}
|
||||
|
||||
export default rootSaga
|
||||
export default rootSaga
|
||||
@@ -8,8 +8,8 @@ import _ from "lodash";
|
||||
import {
|
||||
postAdAnswerRequestSuccess,
|
||||
postAdAnswerRequestFailure,
|
||||
fetchAdsAnsweredSuccess,
|
||||
fetchAdsAnsweredFailure,
|
||||
fetchJobsAnsweredSuccess,
|
||||
fetchJobsAnsweredFailure,
|
||||
fetchAnswerSuccess,
|
||||
fetchAnswerFailure,
|
||||
postMessageAnswerSuccess,
|
||||
@@ -23,7 +23,11 @@ import {
|
||||
|
||||
import {
|
||||
uploadMediaSuccess,
|
||||
uploadMediaFailure
|
||||
uploadMediaFailure,
|
||||
uploadMediaPresSuccess,
|
||||
uploadMediaPresFailure,
|
||||
uploadMediaCvSuccess,
|
||||
uploadMediaCvFailure
|
||||
} from "../actions/media";
|
||||
import AuthRouter from "../pages/AuthRouter";
|
||||
|
||||
@@ -34,7 +38,7 @@ export function* postAdAnswerRequestSaga(action) {
|
||||
|
||||
if (!!res.data) {
|
||||
yield put(postAdAnswerRequestSuccess(res));
|
||||
Router.push("/Candidatures");
|
||||
Router.push("/CandidatureValidation");
|
||||
}
|
||||
else
|
||||
yield put(postAdAnswerRequestFailure(res));
|
||||
@@ -70,14 +74,54 @@ export function* uploadMediaSaga(action) {
|
||||
}
|
||||
}
|
||||
|
||||
export function* fetchAdsAnsweredRequestSaga(action) {
|
||||
export function* uploadMediaPresSaga(action) {
|
||||
try {
|
||||
const res = yield call(api.answers.fetchAdsAnswered, action.payload);
|
||||
|
||||
const res = yield call(api.medias.uploadMediaPres, action.payload);
|
||||
|
||||
if (!!res.data)
|
||||
yield put(fetchAdsAnsweredSuccess(res));
|
||||
yield put(uploadMediaPresSuccess(res));
|
||||
else
|
||||
yield put(fetchAdsAnsweredFailure(res));
|
||||
yield put(uploadMediaPresFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
if (_.includes(err, "401") || err.response.status === 401) {
|
||||
|
||||
localStorage.setItem('loginRedirect', window.location)
|
||||
Router.push("/Login");
|
||||
}
|
||||
yield put(uploadMediaPresFailure(err.response));
|
||||
}
|
||||
}
|
||||
|
||||
export function* uploadMediaCvSaga(action) {
|
||||
try {
|
||||
|
||||
const res = yield call(api.medias.uploadMediaCv, action.payload);
|
||||
|
||||
if (!!res.data)
|
||||
yield put(uploadMediaCvSuccess(res));
|
||||
else
|
||||
yield put(uploadMediaCvFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
if (_.includes(err, "401") || err.response.status === 401) {
|
||||
|
||||
localStorage.setItem('loginRedirect', window.location)
|
||||
Router.push("/Login");
|
||||
}
|
||||
yield put(uploadMediaCvFailure(err.response));
|
||||
}
|
||||
}
|
||||
|
||||
export function* fetchJobsAnsweredRequestSaga(action) {
|
||||
try {
|
||||
const res = yield call(api.answers.fetchJobsAnswered, action.payload);
|
||||
|
||||
if (!!res.data)
|
||||
yield put(fetchJobsAnsweredSuccess(res));
|
||||
else
|
||||
yield put(fetchJobsAnsweredFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
if (_.includes(err, "401") || err.response.status === 401) {
|
||||
@@ -85,7 +129,7 @@ export function* fetchAdsAnsweredRequestSaga(action) {
|
||||
Router.push("/Login");
|
||||
|
||||
}
|
||||
yield put(fetchAdsAnsweredFailure(err.response));
|
||||
yield put(fetchJobsAnsweredFailure(err.response));
|
||||
}
|
||||
}
|
||||
// {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import { call, put } from "redux-saga/effects";
|
||||
import { fetchAdsSuccess, fetchAdsFailure,
|
||||
fetchAdSuccess, fetchAdFailure,
|
||||
fetchEmphasisAdsSuccess,fetchEmphasisAdsFailure
|
||||
import { fetchJobsSuccess, fetchJobsFailure,
|
||||
fetchJobSuccess, fetchJobFailure,
|
||||
fetchEmphasisJobsSuccess,fetchEmphasisJobsFailure
|
||||
|
||||
} from "../actions/ads";
|
||||
|
||||
@@ -18,44 +18,44 @@ export function* countAdViewRequestSaga(action) {
|
||||
export function* requestAdsSaga(action) {
|
||||
try {
|
||||
|
||||
const res = yield call(api.ads.fetchAds, action.payload);
|
||||
const res = yield call(api.ads.fetchJobs, action.payload);
|
||||
|
||||
if (!!res.data)
|
||||
yield put(fetchAdsSuccess(res));
|
||||
yield put(fetchJobsSuccess(res));
|
||||
else
|
||||
yield put(fetchAdsFailure(res));
|
||||
yield put(fetchJobsFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
yield put(fetchAdsFailure(err.response));
|
||||
yield put(fetchJobsFailure(err.response));
|
||||
}
|
||||
}
|
||||
|
||||
export function* requestAdSaga(action) {
|
||||
try {
|
||||
|
||||
const res = yield call(api.ads.fetchAd, action.payload);
|
||||
const res = yield call(api.ads.fetchJob, action.payload);
|
||||
|
||||
if (!!res)
|
||||
yield put(fetchAdSuccess(res));
|
||||
yield put(fetchJobSuccess(res));
|
||||
else
|
||||
yield put(fetchAdFailure(res));
|
||||
yield put(fetchJobFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
yield put(fetchAdFailure(err.response));
|
||||
yield put(fetchJobFailure(err.response));
|
||||
}
|
||||
}
|
||||
|
||||
export function* requestEmphasisAdsSaga(action) {
|
||||
export function* requestEmphasisJobsSaga(action) {
|
||||
try {
|
||||
|
||||
const res = yield call(api.ads.fetchAds, action.payload);
|
||||
const res = yield call(api.ads.fetchJobs, action.payload);
|
||||
|
||||
if (!!res.data)
|
||||
yield put(fetchEmphasisAdsSuccess(res));
|
||||
yield put(fetchEmphasisJobsSuccess(res));
|
||||
else
|
||||
yield put(fetchEmphasisAdsFailure(res));
|
||||
yield put(fetchEmphasisJobsFailure(res));
|
||||
|
||||
} catch (err) {
|
||||
yield put(fetchEmphasisAdsFailure(err.response));
|
||||
yield put(fetchEmphasisJobsFailure(err.response));
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,8 @@ exports.sendConfirmationEmail = function (nom, prenom, tokenUrl, mail) {
|
||||
const tranport = setup();
|
||||
const email = {
|
||||
from: process.env.EMAIL_FROM,
|
||||
to: process.env.NODE_ENV === 'production'? mail : 'thomas.berrod@e-declic.com',
|
||||
subject: `Bienvenue ${mail} 🔑`,
|
||||
to: process.env.NODE_ENV === 'production'? mail : 'l.laniau@talentstube.com',
|
||||
subject: `Bienvenue ${mail} `,
|
||||
text: `
|
||||
Bonjour ${prenom} ${nom},
|
||||
|
||||
|
||||