Compare commits

...

25 Commits

Author SHA1 Message Date
llaniau 8165d99ff5 sitemap 2021-06-28 08:53:16 +02:00
llaniau f7421f55f4 Epuration code avant MEP 2021-06-28 08:46:10 +02:00
llaniau 6053655e1d Epuration code avant MEP 2021-06-28 08:45:44 +02:00
llaniau 2fd7836c59 Correction faute orthographe 2021-06-22 10:37:57 +02:00
llaniau 68f8f374f4 Mise en ligne profil new 2021-06-14 12:40:51 +02:00
llaniau b1bc57b670 Bug messagerie 2021-06-14 12:28:29 +02:00
llaniau 83a296fbd6 Mise en pre prod 2021-06-07 15:39:50 +02:00
llaniau 62f1658bbe US 555 : onglet messagerie 2021-06-07 15:37:12 +02:00
llaniau 7acb3b4aff Bug Helmet 2021-05-31 16:33:53 +02:00
llaniau d563cc52f4 Mise en place du composant Helmet 2021-05-31 14:40:19 +02:00
llaniau c9ab5b0c8c Bug maps 2021-05-31 13:12:51 +02:00
llaniau a4d366ef3e Google maps sans async 2021-05-31 13:00:39 +02:00
llaniau 1197b6c144 Logo defilant 2021-05-31 12:54:49 +02:00
llaniau 9371b7a7bc MEP zvec mise a jour profil 2021-05-31 12:51:03 +02:00
llaniau 165d888ac1 Test vimeo sans retour 2021-05-31 12:07:25 +02:00
llaniau f850cae364 Faute orthographe 2021-05-31 11:23:39 +02:00
llaniau 75ae9664cf MEP V2.10.6_prod (page secrete) 2021-05-31 11:20:08 +02:00
llaniau 3c39e8da12 Mise en forme détail de candiature 2021-05-25 17:41:54 +02:00
llaniau d8ded1e8d7 Profil 6 info + cv 2021-05-25 11:20:13 +02:00
llaniau 3cb2bc5549 profil 5 2021-05-25 10:48:23 +02:00
llaniau ee98e61d97 Mention legales 2021-05-25 10:44:14 +02:00
llaniau 99e19dfc54 Config MEP 2.10.4 2021-05-25 10:40:55 +02:00
llaniau 9bc0696d8d MEP pour test profil 2021-05-25 10:40:10 +02:00
llaniau 580175126b Sitemap 2021-05-17 11:02:39 +02:00
llaniau 41b89bf4b8 MEP V2.10.3 2021-05-17 10:53:12 +02:00
34 changed files with 3641 additions and 912 deletions
+33 -8
View File
@@ -6,6 +6,8 @@ import VideoVimeo from './VideoVimeo'
import ChatCardMessage from './ChatCardMessage'
import _ from "lodash"
import Ar from "lodash/array"
import {TextField, Button, Grid, Hidden} from '@material-ui/core';
import ButtonBase from '@material-ui/core/ButtonBase';
const useStyles = makeStyles(theme => ({
card: {
@@ -31,14 +33,14 @@ const useStyles = makeStyles(theme => ({
padding: theme.spacing(2,0),
},
currentUserBubble: {
background: theme.palette.primary.important,
alignSelf: 'flex-end',
},
currentMessageSender: {
color: theme.palette.primary.important,
},
otherUserBubble: {
background: theme.palette.primary.main,
alignSelf: 'flex-start',
},
otherMessageSender: {
@@ -55,6 +57,21 @@ const useStyles = makeStyles(theme => ({
},
},
cartoucheChat: {
// display: 'flex',
padding: theme.spacing(2) + 'px 18vw'
}
,
grille: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
paddingLeft : theme.spacing(4),
marginBottom: "30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color: theme.palette.primary.dark
},
}));
export default function ChatCard(props) {
@@ -65,10 +82,16 @@ export default function ChatCard(props) {
const bubbleClass = (userFirstName === props.message.sender.firstname && userLastName === props.message.sender.lastname) ? classes.currentUserBubble : classes.otherUserBubble
const messageSenderClass = (userFirstName === props.message.sender.firstname && userLastName === props.message.sender.lastname) ? classes.currentMessageSender : classes.otherMessageSender
const bubbleSide = (userFirstName === props.message.sender.firstname && userLastName === props.message.sender.lastname) ? 'right' : 'left'
// const logoUrl = (props.answer.ad
// ? (props.answer.ad.company.logo
// ? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + this.props.answer.ad.company.logo
// : publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg")
// : "")
const logoUrl = ""
return (
<Fragment>
<section className={classes.grille}>
<ChatCardMessage side={bubbleSide} firstname={props.message.sender.firstname} lastname={props.message.sender.lastname} picture={userPicture}
video={
(props.message.video)
@@ -77,17 +100,19 @@ export default function ChatCard(props) {
message={
(props.message.video)
? (<VideoVimeo classesOverride={ classes.videoVimeo } videoId={Ar.last(_.split(props.message.video.cdn_url, '/'))} />)
: props.message.content}
: ""}
messageTexte = {props.message.content}
messageSenderClass={messageSenderClass} bubbleClass={bubbleClass}/>
messageSenderClass={messageSenderClass} bubbleClass={bubbleClass}
envoyeLe={(new Date(props.message.c_time)).toLocaleDateString("fr-FR")}
envoyeA ={(new Date(props.message.c_time)).toLocaleTimeString("fr-FR")}/>
<Typography
className={classes.messageDate}
align="center"
>
Envoyé le {(new Date(props.message.c_time)).toLocaleDateString("fr-FR")} à {(new Date(props.message.c_time)).toLocaleTimeString("fr-FR")}
{/* Envoyé le {(new Date(props.message.c_time)).toLocaleDateString("fr-FR")} à {(new Date(props.message.c_time)).toLocaleTimeString("fr-FR")} */}
</Typography>
</Fragment>
</section>
)
}
+37 -11
View File
@@ -1,5 +1,6 @@
import React from 'react'
import { Typography } from '@material-ui/core';
import { Grid} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import _ from "lodash"
@@ -15,13 +16,18 @@ const useStyles = makeStyles(theme => ({
justifyContent: 'flex-end',
},
messageSender: {
fontSize: '0.9em',
fontWeight: '300',
color: theme.palette.primary.important,
fontSize: '1em',
fontWeight: '600',
color: theme.palette.primary.dark,
},
messageContent: {
fontWeight: '300',
color: theme.palette.secondary.main,
fontWeight: '600',
color: theme.palette.primary.dark,
},
messageTexteContent: {
marginTop: theme.spacing(1),
},
userBubble: {
width: 'auto',
@@ -57,17 +63,27 @@ const useStyles = makeStyles(theme => ({
},
second: {
order: 2,
},
grille: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
paddingLeft : theme.spacing(4),
marginBottom: "30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color: theme.palette.primary.dark
}
}));
export default function ChatCardMessage(props) {
const { side, firstname, lastname, picture, message, messageTexte, video, messageSenderClass, bubbleClass } = props;
const { side, firstname, lastname, picture, message, messageTexte, video, messageSenderClass, bubbleClass, envoyeLe, envoyeA } = props;
const classes = useStyles();
const userBubble = (video) ? classes.userBubble +' '+ classes.userBubbleVideo : classes.userBubble
return (
<section className={(side==='left')? classes.userMessageLeft : classes.userMessageRight }>
<div >
{picture ?
<img alt="talents-tube" src={`http://recruteur.talentstube.com/uploads/img/${picture}`} className={(side==='left')? classes.first+' '+classes.avatar : classes.second +' '+classes.avatar} />
:
@@ -75,20 +91,30 @@ export default function ChatCardMessage(props) {
}
<div className={(side==='left')? classes.second : classes.first}>
<Typography
className={classes.messageSender +' '+ messageSenderClass}
className={classes.messageSender }
>
{firstname + ' ' + lastname}
</Typography>
<Typography
className={classes.messageSender }
>
Envoyé le {envoyeLe} à {envoyeA}
</Typography>
<div className={userBubble + ' ' + bubbleClass}>
<Typography
className={classes.messageContent}
>
{message}
{messageTexte}
<br></br>
<span className={classes.messageTexteContent}>{messageTexte== message? "" : messageTexte}</span>
</Typography>
</div>
</div>
</section>
</div>
)
}
+334
View File
@@ -0,0 +1,334 @@
import React, { Fragment } from 'react';
import { connect } from "react-redux";
import { fetchCurrentUserRequest } from '../../actions/user'
import { fetchCompanyRequest } from '../../actions/companies'
import { uploadMediaCv } from '../../actions/mediaCv'
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 LoaderVideo from '../templates/loaderVideo'
import Snack from '../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';
import Description from '@material-ui/icons/Description';
import Grid from '@material-ui/core/Grid';
import Container from '@material-ui/core/Container';
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.dark,
},
importButton: {
color: "#1e2327",
backgroundColor: "#fff",
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: "#1e2327",
backgroundColor: "#fff",
}
},
grille :{
paddingTop:theme.spacing(4),
paddingRight:"30px",
width: "100%",
marginBottom:"30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color:theme.palette.primary.dark
},
grille2 :{
margin:'10px',
width: "100%",
marginBottom:"30px",
},
button: {
width:"200px",
textTransform: 'inherit',
margin: theme.spacing(0, 8),
padding: theme.spacing(1.2, 2),
[theme.breakpoints.up('sm')]: {
margin: 'auto',
},
},
boutonMobile:{
width:"200px",
textAlign :"center",
color: theme.palette.secondary.main,
backgroundColor: theme.palette.primary.important,
margin : "0px !important"
},
lien:{
textDecoration:'none',
color:'#fff'
},
centered:{
textAlign:"center"
}
});
const { publicRuntimeConfig } = getConfig();
class Etape3 extends React.Component {
state = {
loading: true,
openSnack: false,
cv:false,
errors: {},
success : {}
};
componentDidMount() {
localStorage.setItem('loginRedirect', window.location.pathname)
if(!!!localStorage.getItem('ttJWT'))
{
Router.push("/Login")
}
else
this.setState({
loading: false,
cvLink: this.props.user.cv
})
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log(nextProps);
this.setState({
cvLink: nextProps.cvLink,
loading: nextProps.loading,
openSnack: !!!_.isEmpty(nextProps.errors),
errors: !!!nextProps.errors ? { errors: { message: "" } } : nextProps.errors,
})
if (nextProps.mediaCv.statusCv === 'success') {
const success = {};
success.message ="Profil mis à jour";
console.log("CV mis à jour!!!")
if(nextProps.mediaCv) console.log(nextProps.mediaCv.message)
this.setState({
cvLink: nextProps.mediaCv.message,
})
this.setState({ success });
}
}
inputFilesystemChangeCv = (e) => {
this.uploadMediaCv(e)
}
uploadMediaCv = (e) => {
var file = e.target.files[0]
const data = new FormData()
data.append('upload', file)
console.log ("envoi de cv")
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(classes) {
console.log("afficher lien");
if (this.state.cvLink !="") {
return (
<Fragment>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<div className={classes.centered} >
<Typography >
<a href={publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.postedContentCv + this.state.cvLink}
target="_blank" className={classes.lien}
>
<Button
variant="contained"
className={classes.button + ' ' + classes.boutonMobile}
>Visualiser mon CV
</Button>
</a>
<br />
</Typography>
</div>
</Fragment>
);
}
return "";
}
render() {
const { classes, company } = this.props;
const { loading } = this.state;
return (
<Grid
container
direction="row"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={12} md={12} xl={12} xs={12} className={classes.grilleGauche}>
<div id="cv">
<Typography
align="center"
gutterBottom
variant="headline"
variant="h6"
component="h2"
className={classes.h6}>
<Description className={classes.menuIcon}></Description> Curriculum vitae
</Typography>
<Typography
align="center">Importez votre CV pour permettre aux recruteurs den savoir plus sur vous.
</Typography>
</div>
<Fragment>
{ loading ?
<LoaderVideo textePrincipal="Votre candidature vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> :
<Grid
container
spacing={4}
direction="row"
alignItems="flex-start"
className={classes.grille2}
justify="center"
alignItems="center">
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<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-cv"
onChange={this.inputFilesystemChangeCv}
/>
<label htmlFor="import-button-file-cv">
<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>&nbsp;</Hidden>
{this.AfficherLienCv(classes)}
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
</Fragment>
</Grid>
</Grid>
}
</Fragment>
</Grid>
</Grid>
);
}
}
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.user.cv,
loading: !!state.media.loading,
cv : true,
mediaCv: state.mediaCv,
//errors: errorMessageSelector(state),
user: state.user,
company: state.company
};
}
export default withStyles(styles)(connect(mapStateToProps, { fetchCurrentUserRequest, fetchCompanyRequest, uploadMediaCv })(Etape3));
+276 -437
View File
@@ -2,17 +2,12 @@ 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 {
Grid
} from '@material-ui/core';
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 { Typography, Hidden } from '@material-ui/core';
import AccountProfile from '../organisms/AccountProfile';
import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';
import {
Button,
@@ -24,13 +19,6 @@ import { geocodeByAddress } from 'react-places-autocomplete'
//US487
import Autosuggest from 'react-autosuggest';
import VideoCam from '@material-ui/icons/Videocam';
import Send from '@material-ui/icons/Send';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
const styles = theme => ({
container: {
@@ -42,8 +30,8 @@ const styles = theme => ({
alignItems: 'center',
justifyContent: 'center',
padding: '24px',
paddingBottom: theme.spacing(3),
marginBottom: theme.spacing(3),
paddingBottom: theme.spacing(8),
marginBottom: theme.spacing(8),
'&>div': {
marginTop: theme.spacing(1.5),
marginBottom: theme.spacing(1.5),
@@ -77,7 +65,6 @@ const styles = theme => ({
},
labelGeoloc:{
paddingLeft:"14px",
textAlign :"left !important",
fontSize: "0.8rem",
color:"#1E2327",
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
@@ -93,73 +80,7 @@ const styles = theme => ({
},
conteneurGoogleComposant:{
paddingLeft:"14px"
},
profil:{
padding: "0px 64px",
fontSize: "1.5em",
marginTop: "32px",
textAlign: "center",
fontFamily: "Roboto",
fontWeight: "600",
marginBottom: "24px",
},
menuIcon:{
color: theme.palette.primary.dark,
},
menu:{
color: theme.palette.primary.main,
fontSize:"1em",
textTransform:"uppercase",
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
},
information:{
padding: "1em",
width: "100%",
backgroundColor: theme.palette.secondary.main,
borderRadius: "5px",
marginBottom:"30px",
borderColor: "1px solid #E5E5E6"
},
grille :{
paddingTop:theme.spacing(4),
paddingBottom:theme.spacing(4),
width: "100%",
marginBottom:"30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color:theme.palette.primary.dark
},
menuLien:{
fontSize:"1em",
textTransform:"uppercase",
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
color: theme.palette.primary.dark,
textDecoration :"none",
'&:hover': {
color: theme.palette.primary.dark,
},
'&:active': {
color: theme.palette.primary.dark,
},
'&:visited': {
color: theme.palette.primary.dark,
},
},
grilleGauche :{
textAlign :"center"
},
grilleDroite :{
textAlign :"center"
},
grilleBas :{
backgroundColor: theme.palette.secondary.dark,
}
});
const { publicRuntimeConfig } = getConfig();
@@ -241,7 +162,6 @@ class AccountEtape1 extends Component {
this.setState({
firstname: nextProps.user.firstname,
lastname: nextProps.user.lastname,
alias: nextProps.user.alias,
phone: nextProps.user.phone,
email: nextProps.user.email,
linkedin: nextProps.user.linkedin,
@@ -263,7 +183,6 @@ class AccountEtape1 extends Component {
this.setState({
firstname: this.props.user.firstname,
lastname: this.props.user.lastname,
alias: this.props.user.alias,
phone: this.props.user.phone,
email: this.props.user.email,
address1: this.props.user.address1,
@@ -367,7 +286,6 @@ class AccountEtape1 extends Component {
this.setState({ lat: obj.lat.toString()})
this.setState({ lng: obj.lng.toString()})
}
this.soumettre("geoloc", "unitaire");
// console.log("GEOLOC ON geocodeByAddress")
@@ -448,13 +366,9 @@ class AccountEtape1 extends Component {
soumettre(champ, type){
console.log("soumettre");
console.log(champ);
let errors = false;
const errors = this.validate(this.state, champ, type);
const success = {};
if(champ!="geoloc"){
errors = this.validate(this.state, champ, type);
this.setState({ errors });
}
this.setState({ errors });
if (!this.state.errors || !this.state.errors.message){
success.message ="Profil mis à jour";
@@ -474,31 +388,19 @@ class AccountEtape1 extends Component {
data.append('twitter', this.state.twitter)
data.append('website', this.state.website)
console.log("GEOLOC ON SUBMIT")
console.log(this.state.geoloc)
if(this.state.geoloc){
data.append('geoloc', this.state.geoloc)
console.log(this.state.street_number)
console.log(this.state.route)
console.log(this.state.locality)
console.log(this.state.administrative_area_level_2)
console.log(this.state.administrative_area_level_1)
console.log(this.state.country)
console.log(this.state.postal_code)
console.log(this.state.formatted_address)
console.log(this.state.lat)
console.log(this.state.lat)
data.append('street_number', this.state.street_number.replace('"', ''))
data.append('route', this.state.route.replace('"', ''))
data.append('locality', this.state.locality.replace('"', ''))
data.append('administrative_area_level_2', this.state.administrative_area_level_2.replace('"', ''))
data.append('administrative_area_level_1', this.state.administrative_area_level_1.replace('"', ''))
data.append('country', this.state.country.replace('"', ''))
data.append('postal_code', this.state.postal_code.replace('"', ''))
data.append('formatted_address', this.state.formatted_address.replace('"', ''))
data.append('lat', this.state.lat)
data.append('lng', this.state.lng)
}
console.log(this.state)
data.append('geoloc', this.state.geoloc)
data.append('street_number', this.state.street_number.replace('"', ''))
data.append('route', this.state.route.replace('"', ''))
data.append('locality', this.state.locality.replace('"', ''))
data.append('administrative_area_level_2', this.state.administrative_area_level_2.replace('"', ''))
data.append('administrative_area_level_1', this.state.administrative_area_level_1.replace('"', ''))
data.append('country', this.state.country.replace('"', ''))
data.append('postal_code', this.state.postal_code.replace('"', ''))
data.append('formatted_address', this.state.formatted_address.replace('"', ''))
data.append('lat', this.state.lat)
data.append('lng', this.state.lng)
//Compétences
data.append('appellationId', this.state.appellationId)
data.append('appellationLibelle', this.state.appellationLibelle)
@@ -560,16 +462,16 @@ class AccountEtape1 extends Component {
// inputFilesystemChange = (e) => {
inputFilesystemChange = (e) => {
// console.log("inputFilesystemChange");
// var file = e.target.files[0]
// this.setState({ picture: file })
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)
// }
const data = new FormData()
data.append('file', file)
this.props.updateUserPictureRequest(data)
}
// METIER
// Filter logic
@@ -695,340 +597,277 @@ class AccountEtape1 extends Component {
const searchOptions = {
componentRestrictions: { country: ['fr'] },
}
return (
<section >
<Typography align="center" className={classes.profil}>
Mon profil
</Typography>
<Grid
container
direction="row"
justify="space-between"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={6} md={6} xl={6} xs={12} className={classes.grilleGauche}>
<a className={classes.menuLien}
href={publicRuntimeConfig.cvThequeUrl+"/talent/"+this.state.alias}
target="_blank">
<div><VideoCam className={classes.menuIcon}></VideoCam></div>
<span className={classes.menuLien} >Voir mon profil Talents Tube</span>
</a>
</Grid>
<Grid item lg={6} md={6} xl={6} xs={12} className={classes.grilleDroite}>
<a className={classes.menuLien}
target="_blank"
href={"https://www.facebook.com/sharer/sharer.php?u=" + publicRuntimeConfig.cvThequeUrl + "/talent/" + user.alias + "%2F&amp;src=sdkpreparse"}
>
<div><Send className={classes.menuIcon}></Send></div>
<span className={classes.menuLien}>Partager mon profil</span>
</a>
</Grid>
</Grid>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Grid
container
<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" />} */}
direction="row"
justify="space-between"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={12} md={12} xl={12} xs={12} >
<div>
{/* {!!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()}
<Typography
align="center"
gutterBottom
variant="headline"
variant="h6"
component="h2"
className={classes.h6}>
<AccountCircleIcon className={classes.menuIcon}></AccountCircleIcon> <div id="information"></div>Mes informations
</Typography>
<Typography
align="center">Renseignez vos coordonnées pour permettre aux recruteurs de vous contacter plus facilement.</Typography>
</div>
<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" />} */}
<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}
/>
{/* {!!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="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
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
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="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
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
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}
/>
<Autosuggest
suggestions={suggestionsMetier}
onSuggestionsFetchRequested={this.onSuggestionsMetierFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsMetierClearRequested}
getSuggestionValue={this.getSuggestionMetierValue}
renderSuggestion={this.renderSuggestionMetier}
inputProps={inputPropsMetier}
/>
<input type="hidden" id="appellation_id" value={this.state.appellationId =='null' || this.state.appellationId =='' ? '' :this.state.appellationId}></input>
<input type="hidden" id="appellation_libelle" value={this.state.appellationLibelle =='null' || this.state.appellationLibelle =='' ? '' :this.state.appellationLibelle}></input>
<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}
/>
<Autosuggest
suggestions={suggestionsMetier}
onSuggestionsFetchRequested={this.onSuggestionsMetierFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsMetierClearRequested}
getSuggestionValue={this.getSuggestionMetierValue}
renderSuggestion={this.renderSuggestionMetier}
inputProps={inputPropsMetier}
/>
<input type="hidden" id="appellation_id" value={this.state.appellationId =='null' || this.state.appellationId =='' ? '' :this.state.appellationId}></input>
<input type="hidden" id="appellation_libelle" value={this.state.appellationLibelle =='null' || this.state.appellationLibelle =='' ? '' :this.state.appellationLibelle}></input>
{/* <TextField
name="currentJob"
id="outlined"
label="Poste actuel"
required
className={classes.textField}
classes={{ root: classes.rootTextfield }}
variant="outlined"
value={this.state.currentJob =='null' || this.state.currentJob =='' ? '' :this.state.currentJob}
onChange={this.handleChange}
onBlur={this.onBlur}
/> */}
<div className={classes.container}>
<div
className={classes.conteneurGoogle}
classes={{ root: classes.rootTextfield }}
style={{ position: 'relative', zIndex:2, width: '100%' }}>
<label htmlFor="outlined-required"
className={classes.labelGeoloc}>
Adresse
</label>
<div className={classes.conteneurGoogleComposant}>
<GooglePlaceAutocomplete
style={{ paddingLeft:'14px !important', left: 0, right: 0, zIndex: '2 !important', width: '100%', textAlign:"left !important", }}
name="location"
label="Location"
id="outlined-required"
variant="outlined"
textFieldProps={{ id: "outlined-required" }}
className={classes.textField}
classes={{ root: classes.rootTextfield }}
options={this.searchOptions}
onSuggestionSelected={this.onSuggestionSelected}
textFieldProps={{ onChange: (e) => this.onChange(e), value: this.state.value, placeholder: 'Ex : Rue de Rivoli, Paris, France', fullWidth: true, size:"small"}}
types={['(regions)']}
componentRestrictions={{country: 'fr'}}
renderTarget={() => (
<div
style={{
width: '100%',
zIndex:9
}}
>
</div>
)}
/>
</div>
{/* <TextField
name="currentJob"
id="outlined"
label="Poste actuel"
required
className={classes.textField}
classes={{ root: classes.rootTextfield }}
variant="outlined"
value={this.state.currentJob =='null' || this.state.currentJob =='' ? '' :this.state.currentJob}
onChange={this.handleChange}
onBlur={this.onBlur}
/> */}
<div className={classes.container}>
<div
className={classes.conteneurGoogle}
classes={{ root: classes.rootTextfield }}
style={{ position: 'relative', zIndex:2, width: '100%' }}>
<label htmlFor="outlined-required"
className={classes.labelGeoloc}>
Adresse
</label>
<div className={classes.conteneurGoogleComposant}>
<GooglePlaceAutocomplete
style={{ paddingLeft:'14px !important', left: 0, right: 0, zIndex: '2 !important', width: '100%' }}
name="location"
label="Location"
id="outlined-required"
variant="outlined"
textFieldProps={{ id: "outlined-required" }}
className={classes.textField}
value="test"
classes={{ root: classes.rootTextfield }}
options={this.searchOptions}
onSuggestionSelected={this.onSuggestionSelected}
textFieldProps={{ onChange: (e) => this.onChange(e), value: this.state.value, placeholder: 'Ex : Rue de Rivoli, Paris, France', fullWidth: true, size:"small"}}
types={['(regions)']}
componentRestrictions={{country: 'fr'}}
renderTarget={() => (
<div
style={{
width: '100%',
zIndex:9
}}
>
</div>
)}
/>
</div>
{/* <Input
name="geoloc"
id="geoloc"
label="geoloc"
ref="geoloc"
onChange={this.handleChange}
value={this.state.geoloc =='null' || this.state.geoloc =='' ? '' :this.state.geoloc}
/> */}
</div>
{/* <TextField
name="address1"
id="outlined"
label="Adresse"
className={classes.textField}
classes={{ root: classes.rootTextfield }}
variant="outlined"
value={this.state.address1 ? this.state.address1 : ''}
onChange={this.handleChange}
onBlur={this.onBlur}
{/* <Input
name="geoloc"
id="geoloc"
label="geoloc"
ref="geoloc"
onChange={this.handleChange}
value={this.state.geoloc =='null' || this.state.geoloc =='' ? '' :this.state.geoloc}
/> */}
</div>
{/* <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 : ''}
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 : ''}
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 : ''}
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 : ''}
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 : ''}
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 : ''}
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 : ''}
onChange={this.handleChange}
onBlur={this.onBlur}
/> */}
{/* </div> */}
{/* <TextField
name="city"
id="outlined"
label="Ville"
className={classes.textField}
classes={{ root: classes.textFieldSmall }}
variant="outlined"
value={this.state.city ? this.state.city : ''}
onChange={this.handleChange}
onBlur={this.onBlur}
/> */}
<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 =='null' || this.state.linkedin =='' ? '' :this.state.linkedin}
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 : ''}
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 =='null' || this.state.linkedin =='' ? '' :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 =='null' || this.state.twitter =='' ? '' :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 =='null' || this.state.website =='' ? '' :this.state.website}
onChange={this.handleChange}
onBlur={this.onBlur}
/>
<Button
onClick={this.refreshPage}
variant="contained"
color="primary"
className={classes.button}>
Enregistrer
</Button>
<TextField
name="twitter"
id="outlined"
label="Twitter"
className={classes.textField}
classes={{ root: classes.rootTextfield }}
variant="outlined"
placeholder="http://twitter.com/.."
value={this.state.twitter =='null' || this.state.twitter =='' ? '' :this.state.twitter}
onChange={this.handleChange}
onBlur={this.onBlur}
/>
<TextField
name="website"
id="outlined"
label="Site internet"
className={classes.textField}
variant="outlined"
placeholder="http://monsite.fr"
value={this.state.website =='null' || this.state.website =='' ? '' :this.state.website}
onChange={this.handleChange}
onBlur={this.onBlur}
/>
<Button
onClick={this.refreshPage}
variant="contained"
color="primary"
</form>
</Grid>
</Grid>
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> */}
@@ -1047,4 +886,4 @@ function mapStateToProps(state, ownProps) {
};
}
export default withStyles(styles)(connect(mapStateToProps, { updateUserRequest })(AccountEtape1));
export default withStyles(styles)(connect(mapStateToProps, { updateUserRequest })(AccountEtape1));
+113 -176
View File
@@ -20,7 +20,6 @@ import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from
import Grid from '@material-ui/core/Grid';
import Container from '@material-ui/core/Container';
import Hidden from '@material-ui/core/Hidden';
import Movie from '@material-ui/icons/Movie';
const styles = theme => ({
container: {
@@ -59,8 +58,8 @@ const styles = theme => ({
height: "100%"
},
conseilButton: {
color: "#1e2327",
backgroundColor: "#fff",
color: "#ffffff",
backgroundColor: "#25D89A",
padding: theme.spacing(3, 2),
margin: theme.spacing(1),
width: "100%",
@@ -68,12 +67,11 @@ const styles = theme => ({
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: "#1e2327",
backgroundColor: "#fff",
color: "#ffffff",
backgroundColor: "#25D89A",
}
},
captureButton: {
width:"100%",
color: theme.palette.secondary.main,
backgroundColor: theme.palette.primary.main,
padding: theme.spacing(5, 2),
@@ -84,8 +82,8 @@ const styles = theme => ({
},
},
importButton: {
color: "#1e2327",
backgroundColor: "#fff",
color: theme.palette.primary.main,
backgroundColor: theme.palette.secondary.main,
padding: theme.spacing(3, 2),
margin: theme.spacing(1),
width: "100%",
@@ -93,8 +91,8 @@ const styles = theme => ({
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: "#1e2327",
backgroundColor: "#fff",
color: theme.palette.primary.main,
backgroundColor: theme.palette.secondary.main,
}
},
InputKeyboardArrowDownIconBlank: {
@@ -104,21 +102,12 @@ const styles = theme => ({
},
InputKeyboardArrowDownIcon: {
fontSize: '2.5em',
color: "#1e2327",
color: "#1689FB",
textAlign: "right"
},
buttons :{
display: "inline-table",
},
grille :{
paddingTop:theme.spacing(4),
width: "100%",
marginBottom:"30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color:theme.palette.primary.dark
},
}
});
const Recorder = dynamic(() => import ('../organisms/Recorder'), {ssr: false})
class Etape2 extends React.Component {
@@ -128,8 +117,7 @@ class Etape2 extends React.Component {
data: {},
openSnack: false,
errors: {},
success : {},
openStudio : false
success : {}
};
@@ -158,9 +146,9 @@ class Etape2 extends React.Component {
video: nextProps.video
})
//window.location.reload(false);
if (nextProps.media.statusPres === 'success') {
if (nextProps.media.status === 'success') {
const success = {};
success.message ="Profil mise à jour.";
success.message ="Vidéo mise à jour";
this.setState({ success });
this.setActiveStep(1);
}
@@ -170,7 +158,7 @@ class Etape2 extends React.Component {
this.setState({activeStep: step})
}
inputFilesystemChangePres = (e) => {
inputFilesystemChange = (e) => {
this.uploadMediaPres(e)
}
@@ -180,7 +168,7 @@ class Etape2 extends React.Component {
uploadMediaPres = (e) => {
var file = e.target.files[0]
console.log ("envoi de video pres")
const data = new FormData()
data.append('upload', file)
//this.setState({ videoPres: videoPres })
@@ -208,188 +196,137 @@ class Etape2 extends React.Component {
handleClose = (event, reason) => {
this.setState({openSnack: false});
}
realise =() =>{
console.log("realise");
this.setState({ openStudio: true});
}
retour =() =>{
console.log("retour");
this.setState({ openStudio: false});
}
render() {
const {classes, company} = this.props;
const {loading, activeStep} = this.state;
if (typeof global.navigator === 'undefined') global.navigator = {};
let video;
if (this.state.videoPres) {
video = <VideoVimeo videoId={Ar.last(_.split(this.state.videoPres, '/'))} autoplay='1' classesOverride="videoPresentation"/>;
} else {
video = "";
}
if (typeof global.navigator === 'undefined') global.navigator = {};
if (typeof global.maps === 'undefined') global.maps = {};
return (
<Grid
container
direction="row"
justify="space-between"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={12} md={12} xl={12} xs={12} >
<div id="video">
<section className={classes.container}>
<Fragment>
{this.AfficherSuccess()}
{ loading ? <LoaderVideo textePrincipal="Votre vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> : <div></div> }
<Typography
align="center"
gutterBottom
variant="headline"
variant="h6"
component="h2"
className={classes.h6}>
<Movie className={classes.menuIcon}></Movie> Vidéo de présentation
</Typography>
<Typography
align="center">Donnez envie au recruteur de vous rencontrer grâce à la vidéo !</Typography>
</div>
<Fragment>
{this.AfficherSuccess()}
{ loading ? <LoaderVideo textePrincipal="Votre vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> : <div></div> }
<div className={classes.root}>
<Hidden xsUp>
&nbsp;
<div className={classes.root}>
<Hidden xsUp>
&nbsp;
</Hidden>
<Container maxWidth="md">
<Grid container
justify="center"
alignItems="center"
spacing={2}
className={classes.buttons}>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<Container maxWidth="md">
<Grid container
justify="center"
alignItems="center"
spacing={2}
className={classes.buttons}>
<Grid item xs={12} sm={12} md={12} lg={6} lg={6}>
{ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ?
(
<Fragment >
<input
type="file" accept="video/*" capture="camcorder"
className={classes.input}
style={{ display: 'none' }}
id="record-button-file"
multiple
onChange={this.inputCamRecorderChange}
/>
<label htmlFor="record-button-file">
<Button component="span" className={classes.captureButton} classes={{ root: classes.rootButton }}>
<img alt="talents-tube" src='/static/images/capture.svg' className={classes.iconButton} />
<Typography align="left" className={classes.textButton}>
Je <span className={classes.underlined}>réalise</span> ma vidéo de présentation
</Typography>
<KeyboardArrowRightIcon className={ classes.InputKeyboardArrowRightIcon }/>
</Button>
</label>
</Fragment>
):
(
<Fragment>
{this.state.openStudio == false ?
<Button component="span" className={classes.captureButton} classes={{ root: classes.rootButton }} onClick={this.realise}>
<img alt="talents-tube" src='/statique/images/capture.svg' className={classes.iconButton} />
<Typography align="left" className={classes.textButton}>
Je <span className={classes.underlined}>réalise</span> ma vidéo de présentation
</Typography>
<KeyboardArrowRightIcon className={ classes.InputKeyboardArrowRightIcon }/>
</Button>
:
<div className={classes.recorderContainer}>
<Button onClick={this.retour}>Retour au menu</Button>
<Recorder uploader={this.props.uploadMediaPres} titreBouton="Remplacer ma vidéo"/>
</div>
}
{ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ?
(
<Fragment >
<input
type="file" accept="video/*" capture="camcorder"
className={classes.input}
style={{ display: 'none' }}
id="record-button-file"
multiple
onChange={this.inputCamRecorderChange}
/>
<label htmlFor="record-button-file">
<Button component="span" className={classes.captureButton} classes={{ root: classes.rootButton }}>
<img alt="talents-tube" src='/static/images/capture.svg' className={classes.iconButton} />
<Typography align="left" className={classes.textButton}>
Je <span className={classes.underlined}>réalise</span> ma vidéo de présentation
</Typography>
<KeyboardArrowRightIcon className={ classes.InputKeyboardArrowRightIcon }/>
</Button>
</label>
</Fragment>
)
}
</Grid>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<div>
<input
type="file"
accept="video/*"
className={classes.input + ' cypButtonImportVid'}
style={{display: 'none'}}
id="import-button-file-pres"
onChange={this.inputFilesystemChangePres}/>
<label htmlFor="import-button-file-pres">
<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 présentation
):
(
</Typography>
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIcon}/>
</Button>
</label>
</div>
<div>
<label htmlFor="import-conseil">
<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}}
onClick={() => Router.push(`/Conseils`)}>
root: classes.rootButton}}>
<img
alt="talents-tube"
src='/statique/images/comment-faire-une-video-reponse.svg'
src='/statique/images/Import.svg'
className={classes.iconButton}/>
<Typography align="left" className={classes.textButton}>
<span className={classes.underlined}>Comment</span> créer ma vidéo de présentation
J'<span className={classes.underlined}>importe</span> ma vidéo de présentation
</Typography>
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIcon}/>
</Button>
</label>
</div>
</Grid>
<Hidden xsUp>
&nbsp;
</Hidden>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<div className={classes.videoPresentation}>
{video}
</div>
</Grid>
</Grid>
<Hidden xsUp>
&nbsp;
</Hidden>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<div className={classes.videoPresentation}>
{video}
</div>
</Grid>
</Container>
</div>
{/* <div className={classes.textContainer}>
</div> */}
</Fragment>
</Grid>
</Grid>
</Grid>
</Container>
</div>
{/* <div className={classes.textContainer}>
</div> */}
</Fragment>
</section>
);
}
+70 -143
View File
@@ -17,9 +17,8 @@ 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';
import Description from '@material-ui/icons/Description';
import Grid from '@material-ui/core/Grid';
import Container from '@material-ui/core/Container';
const styles = theme => ({
root: {
display: 'flex',
@@ -41,61 +40,21 @@ const styles = theme => ({
},
InputKeyboardArrowDownIcon: {
fontSize: '2.5em',
color: theme.palette.primary.dark,
color: theme.palette.primary.main,
},
importButton: {
color: "#1e2327",
backgroundColor: "#fff",
color: theme.palette.primary.main,
backgroundColor: theme.palette.secondary.main,
padding: theme.spacing(3, 2),
margin: theme.spacing(1),
width: "100%",
textAlign: "right",
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: "#1e2327",
backgroundColor: "#fff",
color: theme.palette.primary.main,
backgroundColor: theme.palette.secondary.main,
}
},
grille :{
paddingTop:theme.spacing(4),
paddingRight:"30px",
width: "100%",
marginBottom:"30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color:theme.palette.primary.dark
},
grille2 :{
margin:'10px',
width: "100%",
marginBottom:"30px",
},
button: {
width:"200px",
textTransform: 'inherit',
margin: theme.spacing(0, 8),
padding: theme.spacing(1.2, 2),
[theme.breakpoints.up('sm')]: {
margin: 'auto',
},
},
boutonMobile:{
width:"200px",
textAlign :"center",
color: theme.palette.secondary.main,
backgroundColor: theme.palette.primary.important,
margin : "0px !important"
},
lien:{
textDecoration:'none',
color:'#fff'
},
centered:{
textAlign:"center"
}
});
@@ -131,12 +90,12 @@ class Etape3 extends React.Component {
openSnack: !!!_.isEmpty(nextProps.errors),
errors: !!!nextProps.errors ? { errors: { message: "" } } : nextProps.errors,
})
if (nextProps.mediaCv.statusCv === 'success') {
this.state.cvLink = nextProps.cvLink;
if (nextProps.loading) {
const success = {};
success.message ="Profil mis à jour";
success.message ="CV mis à jour";
console.log("CV mis à jour!!!")
if(nextProps.mediaCv) console.log(nextProps.mediaCv.message)
if(this.state.cvLink) console.log(this.state.cvLink)
this.setState({ success });
}
@@ -144,7 +103,7 @@ class Etape3 extends React.Component {
}
inputFilesystemChangeCv = (e) => {
inputFilesystemChange = (e) => {
this.uploadMediaCv(e)
}
@@ -153,7 +112,7 @@ class Etape3 extends React.Component {
const data = new FormData()
data.append('upload', file)
console.log ("envoi de cv")
this.props.uploadMediaCv(data)
}
@@ -163,7 +122,6 @@ class Etape3 extends React.Component {
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)}
@@ -174,7 +132,7 @@ class Etape3 extends React.Component {
return "";
}
AfficherLienCv(classes) {
AfficherLienCv() {
console.log("afficher lien");
if (this.state.cvLink !="") {
@@ -186,26 +144,39 @@ class Etape3 extends React.Component {
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</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>&nbsp;</Hidden>
<div className={classes.centered} >
<CardActions>
<Button size="small">MON CV</Button>
</CardActions>
<CardContent>
<Typography >
<a href={publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.postedContentCv + this.state.cvLink}
target="_blank" className={classes.lien}
target="_blank"
style={{
color:'#1689FB',
'&:hover': {
color: '#1689FB',
},
fontWeight: '700',
fontSize: '1em',
}}
>
<Button
variant="contained"
className={classes.button + ' ' + classes.boutonMobile}
>Visualiser mon CV
</Button>
Visualiser mon CV
</a>
<br />
{/* <a href="https://www.permatheque.fr/PDF/mansobufukuoka-larevolutiondunseulbrindepaille.pdf" target="_blank">lien</a> */}
</Typography>
</div>
</CardContent>
</Card>
</Fragment>
);
@@ -218,79 +189,36 @@ class Etape3 extends React.Component {
const { classes, company } = this.props;
const { loading } = this.state;
return (
<Grid
container
direction="row"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={12} md={12} xl={12} xs={12} className={classes.grilleGauche}>
<div id="cv">
<Typography
align="center"
gutterBottom
variant="headline"
variant="h6"
component="h2"
className={classes.h6}>
<Description className={classes.menuIcon}></Description> Curriculum vitae
</Typography>
<Typography
align="center">Importez votre CV pour permettre aux recruteurs den savoir plus sur vous.
.</Typography>
</div>
<Fragment>
{ loading ?
<Fragment>
{ loading ?
<LoaderVideo textePrincipal="Votre candidature vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> :
<Fragment>
{this.AfficherSuccess()}
<LoaderVideo textePrincipal="Votre candidature vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> :
<Grid
container
spacing={4}
direction="row"
alignItems="flex-start"
className={classes.grille2}
justify="center"
alignItems="center">
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<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-cv"
onChange={this.inputFilesystemChangeCv}
/>
<label htmlFor="import-button-file-cv">
<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>&nbsp;</Hidden>
{this.AfficherLienCv(classes)}
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
<Hidden>&nbsp;</Hidden>
</Fragment>
</Grid>
</Grid>
}
</Fragment>
</Grid>
</Grid>
<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>&nbsp;</Hidden>
{this.AfficherLienCv()}
</Fragment>
}
</Fragment>
);
}
@@ -321,7 +249,6 @@ function mapStateToProps(state) {
cvLink : state.mediaCv.message,
loading: !!state.media.loading,
cv : true,
mediaCv: state.mediaCv,
//errors: errorMessageSelector(state),
user: state.user,
company: state.company
File diff suppressed because it is too large Load Diff
+205 -45
View File
@@ -28,8 +28,6 @@ import RefreshIcon from '@material-ui/icons/Refresh';
// from '@material-ui/icons/LocationOn';
import Link from 'next/link'
import Box from '@material-ui/core/Box';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import {
Card,
@@ -65,10 +63,7 @@ const styles = theme => ({
width: '100%',
position: 'fixed',
bottom: 0
},
menu: {
backgroundColor: "#DAE8F2"
},
}
});
const useStyles = makeStyles(theme => ({
@@ -121,9 +116,6 @@ const useStyles = makeStyles(theme => ({
},
resetContainer: {
padding: theme.spacing(3)
},
conteneur:{
backgroundColor: "#f3f3f4",
}
}));
@@ -250,9 +242,11 @@ const AccountProfile = props => {
return skipped.has(step);
};
const handleChange = (event, newValue) => {
const handleChange = (event) => {
setState({
...state,
[event.target.name]: event.target.checked
});
};
function isStepComplete(step) {
@@ -266,44 +260,210 @@ const AccountProfile = props => {
}
return (
<Grid
container
>
<Grid item lg={12} md={12} xl={12} xs={12} >
<div >
<Paper elevation={0} >
<Tabs
value={1}
onChange={handleChange}
indicatorColor="primary"
textColor="theme.palette.primary.dark"
centered
>
<Link href="/Candidatures"><Tab label="Mes candidatures" /></Link>
<Tab label="Mon profil" />
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}
&nbsp; {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 linkedIn</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>
</Tabs>
</Paper>
</div>
</Grid>
<Grid item lg={3} md={3} xl={4} xs={12}>
</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&amp;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={6} md={6} xl={4} xs={12} >
<AccountEtape1 ></AccountEtape1>
<AccountEtape2 ></AccountEtape2>
<AccountEtape3 ></AccountEtape3>
</Grid>
<Grid item lg={3} md={3} xl={4} xs={12}>
<Grid item lg={9} md={6} xl={8} xs={12}>
{getStepContent(activeStep)}
</Grid>
</Grid>
@@ -0,0 +1,325 @@
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
// import AccountStep from "../../components/organisms/AccountStep";
import AccountInfo from '../organisms/AccountInfo';
import AccountVideo from '../organisms/AccountVideo';
import AccountCv from '../organisms/AccountCv';
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 Link from 'next/link'
import Box from '@material-ui/core/Box';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
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
},
menu: {
backgroundColor: "#DAE8F2"
},
});
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)
},
conteneur:{
backgroundColor: "#f3f3f4",
}
}));
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, newValue) => {
};
function isStepComplete(step) {
return completed.has(step);
}
function refresh() {
document
.location
.reload(true);
console.log("refresh")
}
return (
<Grid
container
>
<Grid item lg={12} md={12} xl={12} xs={12} >
<div >
<Paper elevation={0} >
<Tabs
value={1}
onChange={handleChange}
indicatorColor="primary"
textColor="theme.palette.primary.dark"
centered
>
<Link href="/Candidatures"><Tab label="Mes candidatures" /></Link>
<Tab label="Mon profil" />
</Tabs>
</Paper>
</div>
</Grid>
<Grid item lg={3} md={3} xl={4} xs={12}>
</Grid>
<Grid item lg={6} md={6} xl={4} xs={12} >
<AccountInfo ></AccountInfo>
<AccountVideo ></AccountVideo>
<AccountCv ></AccountCv>
</Grid>
<Grid item lg={3} md={3} 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))
+430
View File
@@ -0,0 +1,430 @@
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 LoaderVideo from '../templates/loaderVideo'
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';
import Movie from '@material-ui/icons/Movie';
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: "#1e2327",
backgroundColor: "#fff",
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: "#1e2327",
backgroundColor: "#fff",
}
},
captureButton: {
width:"100%",
color: theme.palette.secondary.main,
backgroundColor: theme.palette.primary.main,
padding: theme.spacing(5, 2),
margin: theme.spacing(1),
boxShadow: '0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 4px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.14)',
'&:hover': {
backgroundColor: theme.palette.primary.main,
},
},
importButton: {
color: "#1e2327",
backgroundColor: "#fff",
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: "#1e2327",
backgroundColor: "#fff",
}
},
InputKeyboardArrowDownIconBlank: {
fontSize: '2.5em',
color: "#ffffff",
textAlign: "right"
},
InputKeyboardArrowDownIcon: {
fontSize: '2.5em',
color: "#1e2327",
textAlign: "right"
},
buttons :{
display: "inline-table",
},
grille :{
paddingTop:theme.spacing(4),
width: "100%",
marginBottom:"30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color:theme.palette.primary.dark
},
});
const Recorder = dynamic(() => import ('./Recorder'), {ssr: false})
class Etape2 extends React.Component {
state = {
loading: true,
activeStep: 0,
data: {},
openSnack: false,
errors: {},
success : {},
openStudio : false
};
componentDidMount() {
localStorage.setItem('loginRedirect', window.location.pathname)
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 ? nextProps.videoPres : this.props.user.videoPres,
video: nextProps.video
})
//window.location.reload(false);
if (nextProps.media.statusPres === 'success') {
const success = {};
success.message ="Profil mise à jour";
this.setState({ success });
this.setActiveStep(1);
}
}
setActiveStep = (step) => {
this.setState({activeStep: step})
}
inputFilesystemChangePres = (e) => {
this.uploadMediaPres(e)
}
inputCamRecorderChange = (e) => {
this.uploadMediaPres(e)
}
uploadMediaPres = (e) => {
var file = e.target.files[0]
console.log ("envoi de video pres")
const data = new FormData()
data.append('upload', file)
//this.setState({ videoPres: videoPres })
console.log("VIDEO PRES OK");
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});
}
realise =() =>{
console.log("realise");
this.setState({ openStudio: true});
}
retour =() =>{
console.log("retour");
this.setState({ openStudio: false});
}
render() {
const {classes, company} = this.props;
const {loading, activeStep} = this.state;
let video;
if (this.props.user.videoPres) {
video = <VideoVimeo videoId={Ar.last(_.split(this.props.user.videoPres, '/'))} autoplay='1' classesOverride="videoPresentation"/>;
} else {
video = "----";
}
if (typeof global.navigator === 'undefined') global.navigator = {};
return (
<Grid
container
direction="row"
justify="space-between"
alignItems="flex-start"
className={classes.grille}
justify="center"
alignItems="center">
<Grid item lg={12} md={12} xl={12} xs={12} >
<div id="video">
<Typography
align="center"
gutterBottom
variant="headline"
variant="h6"
component="h2"
className={classes.h6}>
<Movie className={classes.menuIcon}></Movie> Vidéo de présentation
</Typography>
<Typography
align="center">Donnez envie au recruteur de vous rencontrer grâce à la vidéo !</Typography>
</div>
<Fragment>
{this.AfficherSuccess()}
{ loading ? <LoaderVideo textePrincipal="Votre vidéo est en cours denvoi..." texteSecondaire="Veuillez rester sur la page pendant le chargement qui peut durer plusieurs minutes."/> : <div></div> }
<div className={classes.root}>
<Hidden xsUp>
&nbsp;
</Hidden>
<Container maxWidth="md">
<Grid container
justify="center"
alignItems="center"
spacing={2}
className={classes.buttons}>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
{ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ?
(
<Fragment >
<input
type="file" accept="video/*" capture="camcorder"
className={classes.input}
style={{ display: 'none' }}
id="record-button-file"
multiple
onChange={this.inputCamRecorderChange}
/>
<label htmlFor="record-button-file">
<Button component="span" className={classes.captureButton} classes={{ root: classes.rootButton }}>
<img alt="talents-tube" src='/static/images/capture.svg' className={classes.iconButton} />
<Typography align="left" className={classes.textButton}>
Je <span className={classes.underlined}>réalise</span> ma vidéo de présentation
</Typography>
<KeyboardArrowRightIcon className={ classes.InputKeyboardArrowRightIcon }/>
</Button>
</label>
</Fragment>
):
(
<Fragment>
{this.state.openStudio == false ?
<Button component="span" className={classes.captureButton} classes={{ root: classes.rootButton }} onClick={this.realise}>
<img alt="talents-tube" src='/statique/images/capture.svg' className={classes.iconButton} />
<Typography align="left" className={classes.textButton}>
Je <span className={classes.underlined}>réalise</span> ma vidéo de présentation
</Typography>
<KeyboardArrowRightIcon className={ classes.InputKeyboardArrowRightIcon }/>
</Button>
:
<div className={classes.recorderContainer}>
<Button onClick={this.retour}>Retour au menu</Button>
<Recorder uploader={this.props.uploadMediaPres} titreBouton="Remplacer ma vidéo" />
</div>
}
</Fragment>
)
}
</Grid>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<div>
<input
type="file"
accept="video/*"
className={classes.input + ' cypButtonImportVid'}
style={{display: 'none'}}
id="import-button-file-pres"
onChange={this.inputFilesystemChangePres}/>
<label htmlFor="import-button-file-pres">
<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 présentation
</Typography>
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIcon}/>
</Button>
</label>
</div>
<div>
<label htmlFor="import-conseil">
<Button
component="span"
className={classes.importButton}
classes={{
root: classes.rootButton}}
onClick={() => Router.push(`/Conseils`)}>
<img
alt="talents-tube"
src='/statique/images/comment-faire-une-video-reponse.svg'
className={classes.iconButton}/>
<Typography align="left" className={classes.textButton}>
<span className={classes.underlined}>Comment</span> créer ma vidéo de présentation
</Typography>
<KeyboardArrowDownIcon className={classes.InputKeyboardArrowDownIcon}/>
</Button>
</label>
</div>
</Grid>
<Hidden xsUp>
&nbsp;
</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>
</Grid>
</Grid>
);
}
}
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,39 @@
import React, { Fragment } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import _ from "lodash"
import Ar from "lodash/array"
import VideoVimeo from '../atoms/VideoVimeo'
const useStyles = makeStyles(theme => ({
card: {
width: '100%',
},
title: {
fontSize: '1em',
fontWeight: '500',
},
titleBorder: {
'&:after': {
content: '""',
width: '15px',
borderBottom: 'solid 2px',
borderColor: theme.palette.primary.main + '!important',
display: 'flex',
},
},
video: {
[theme.breakpoints.up('md')]: {
paddingBottom: '35%', /* 16:9 */
},
}
}));
export default function CandidatureDetail(props) {
const classes = useStyles();
return (
<Fragment>
<VideoVimeo classes={{ video: classes.video }} videoId={Ar.last(_.split(props.video.cdn_url, '/'))} />
</Fragment>
);
}
+1 -1
View File
@@ -159,7 +159,7 @@ class AnswerRowComponent extends React.Component {
: publicRuntimeConfig.adListDefaultUrl
const logoUrl = publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + companyR.logo
return (
<Link href={`/Candidature/${rowData.id}`} >
<Link href={`/Answer/${rowData.id}`} >
<Card className={classes.card} >
{rowData.ad ? (
<CardContent className={classes.content}>
+150 -44
View File
@@ -9,8 +9,9 @@ import IconAdd from '@material-ui/icons/Add';
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux'
import { Grid, Hidden} from '@material-ui/core';
import ButtonBase from '@material-ui/core/ButtonBase';
import { Typography } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
card: {
width: '100%',
@@ -44,23 +45,13 @@ const useStyles = makeStyles(theme => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: theme.palette.input.main,
padding: theme.spacing(1),
width: '100%',
[theme.breakpoints.up('md')]: {
padding: theme.spacing(3),
},
},
button: {
backgroundColor: 'inherit',
borderRadius: '0',
'& svg': {
fontSize: '1.5rem',
[theme.breakpoints.up('sm')]: {
fontSize: '2rem',
},
}
},
icon: {
color: theme.palette.secondary.main,
background: theme.palette.primary.important,
@@ -85,6 +76,68 @@ const useStyles = makeStyles(theme => ({
display: 'flex',
},
},
grille: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
paddingLeft : theme.spacing(4),
marginBottom: "30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color: theme.palette.primary.dark
},
menuLien: {
fontSize: "1em",
textTransform: "uppercase",
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
color: theme.palette.primary.dark,
textDecoration: "none",
'&:hover': {
color: theme.palette.primary.dark
},
'&:active': {
color: theme.palette.primary.dark
},
'&:visited': {
color: theme.palette.primary.dark
}
},
grilleGauche: {
textAlign: "center"
},
grilleDroite: {
textAlign: "center"
},
grilleBas: {
backgroundColor: theme.palette.secondary.dark
},
chip: {
marginTop: "10px",
backgroundColor: "#E7F3FF",
color: theme.palette.primary.dark
},
icon: {
color: theme.palette.secondary.dark
},
cartoucheEntreprise: {
// display: 'flex',
padding: theme.spacing(2) + 'px ',
[theme.breakpoints.up('md')]: {
padding: theme.spacing(2) + 'px 18vw',
},
},
textField: {
width: '85%',
'&:disabled': {
color: theme.palette.secondary.dark,
},
'& label': {
color: theme.palette.primary.dark,
},
'& fieldset:hover': {
borderColor: theme.palette.primary.main + ' !important',
},
},
}));
@@ -105,42 +158,95 @@ function Chat(props) {
sendMessage(text);
setText('');
}
// const logoUrl = (props.answer.ad
// ? (props.answer.ad.company.logo
// ? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + this.props.answer.ad.company.logo
// : publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg")
// : "")
const logoUrl = props.logoUrl
return (
<Fragment>
<div className={classes.wrapper}>
<div className={classes.contain}>
{
_.orderBy(messages, ['c_time'], ['asc']).map((message, index) => {
return <ChatCard message={message} key={index}></ChatCard>
})
}
<section className={classes.cartoucheEntreprise}>
<Grid container spacing={2} className={classes.grille}>
<Grid item>
<ButtonBase className={classes.image}>
<img alt="talents-tube" src={logoUrl} className={classes.userAvatar}/>
</ButtonBase>
</Grid>
<Grid item lg={12} xl container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xl>
<Typography gutterBottom variant="subtitle1">
{props.nomCompany}
{/* {(this.props.answer.ad
? (this.props.answer.ad.company.brand_name
? this.props.answer.ad.company.brand_name
: "")
: this.props.answer.company.brand_name)} */}
</Typography>
<Typography variant="body2" gutterBottom>
{props.nomAd}
{/* {this.props.answer.ad
? (this.props.answer.ad.title
? this.props.answer.ad.title
: "Candidature spontanée")
: "Candidature spontanée"} */}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
</section>
<section className={classes.cartoucheEntreprise}>
<Grid container spacing={2} className={classes.grille} direction="column">
<Grid item >
<TextField
fullWidth
multiline
rows={10}
name="chattext"
id="outlined"
label="Envoyer un email"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder={"Ecrivez un message pour l'entreprise"}
variant="outlined"
className={classes.textField}
</div>
</div>
/>
</Grid>
<Grid item>
<Button
onClick={()=>postMessage()}
variant="contained"
color="primary"
className={classes.button}>
Envoyer
</Button>
</Grid>
</Grid>
<Grid container spacing={2} direction="column">
<div>
{
_.orderBy(messages, ['c_time'], ['desc']).map((message, index) => {
return <ChatCard message={message} key={index}></ChatCard>
})
}
</div>
</Grid>
</section>
<div id="F" className={classes.foot}>
<div className={classes.filterForm}>
<TextField
fullWidth
multiline
rows={isWidthUp('md', props.width) ? 8 : 1}
id="standard-search"
name="chattext"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder={"Message"}
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
<Button onClick={()=>postMessage()}
disabled={loadingMessage}
variant="contained"
className={classes.button}>
<ArrowUpwardIcon className={classes.icon}/>
</Button >
</div>
</div>
</Fragment>
+2 -2
View File
@@ -203,7 +203,7 @@ function Footer(props) {
<Link href="/Offres" >
<a>
<Typography gutterBottom color="secondary" component="p" className={classes.textContainer}>
Offre d'emploi
Offres d'emploi
</Typography>
</a>
</Link>
@@ -274,7 +274,7 @@ function Footer(props) {
56 000 Vannes
</Typography>
<Typography gutterBottom color="secondary" component="p" className={classes.textContainer}>
<a href="tel:+33230050631" >02.30.05.06.31 </a>
<a href="tel:+33756850954" >07.56.85.09.54 </a>
</Typography>
{/* <Typography gutterBottom color="secondary" component="p" className={classes.textContainer}>
contact@talentstube.com
+1 -1
View File
@@ -220,7 +220,7 @@ function Footer(props) {
56 000 Vannes
</Typography>
<Typography gutterBottom component="p" className={classes.textContainer}>
<a href="tel:+33230050631" >02.30.05.06.31 </a>
<a href="tel:+33756850954" >*07.56.85.09.54 </a>
</Typography>
{/* <Typography gutterBottom color="secondary" component="p" className={classes.textContainer}>
contact@talentstube.com
+1 -1
View File
@@ -525,7 +525,7 @@ class Header extends React.Component {
</ListItemText>
</ListItem></a>
</Link>
<Link href="/profileStep" >
<Link href="/profil2" >
<a className={classes.lightMenuItem}>
<ListItem classes={{ root: classes.rootListItemIcon }}>
<AccountCircleIcon className={classes.icon} />
@@ -434,7 +434,7 @@ class HeaderPersonnalise extends React.Component {
</ListItemText>
</ListItem></a>
</Link>
<Link href="/profileStep" >
<Link href="/profil2" >
<a className={classes.lightMenuItem}>
<ListItem classes={{ root: classes.rootListItemIcon }}>
<AccountCircleIcon className={classes.icon} />
+1 -1
View File
@@ -845,7 +845,7 @@ function OffreDetail(props) {
</div>
<KeyboardArrowleftIcon className={classes.iconPlay} />
<Typography variant="h3" component="h3" className={classes.playerTexte}>
Lire la vidéo.
Lire la vidéo
</Typography>
</div>
</Link>
+18 -20
View File
@@ -180,31 +180,24 @@ class Recorder extends Component {
// When you pass text in options it just creates a control text,
// which is displayed as tooltip when hovered on
// this button viz the span in you div,
var myButton = this.player.controlBar.addChild("button");
// which is displayed as tooltip when hovered on
// this button viz the span in you div,
var myButton = this.player.controlBar.addChild("button");
// There are many functions available for button component
// like below mentioned in this docs
// https://docs.videojs.com/button.
// You can set attributes and clasess as well.
// There are many functions available for button component
// like below mentioned in this docs
// https://docs.videojs.com/button.
// You can set attributes and clasess as well.
// Getting html DOM
var myButtonDom = myButton.el();
//var myButtonDom2 = myButton2.el();
// Since now you have the html dom element
// you can add click events
// Getting html DOM
var myButtonDom = myButton.el();
// Now I am setting the text as you needed.
// myButtonDom.innerHTML = "Youi";
myButtonDom.onclick = function(){
//alert("Redirecting");
vid.pause();
}
myButtonDom.onclick = function(){
//alert("Redirecting");
vid.pause();
}
// device is ready
@@ -253,6 +246,11 @@ myButtonDom.onclick = function(){
formData.append('upload', this.player.recordedData, "myupload");
this.props.uploader(formData);
console.log("REDIRECTION OU PAS");
console.log(this.props.retour);
if(this.props.retour=="home"){
window.location.replace("/");
}
}
recordPlayer = () => {
+1 -1
View File
@@ -97,7 +97,7 @@ export default {
postAnswer: (payload) => {
return axios.post("/api/answers", { adId: payload.adId, mediaId: payload.mediaId, companyId: payload.companyId }).then(res => res)
},
fetchJobsAnswered: ({ limit = null, order = "", keyword = "", offset = 1 }) => {
fetchJobsAnswered: ({ limit = null, order = "desc", keyword = "", offset = 1 }) => {
return axios.get(`api/answers`, { params: { offset, limit, order, keyword } }).then(res => res.data)
},
fetchAnswer: (payload) => {
+1 -1
View File
@@ -55,7 +55,7 @@ module.exports = withPlugins(
blogUrl: 'https://blog.talentstube.com',
frontServerUrl: 'https://pp.app.talentstube.com/',
cvThequeUrl: 'https://recruteur.talentstube.com',
version : 'V2.10.2',
version : 'V2.11.2',
adListDefaultUrl: '/statique/images/default/default_picture_company.jpg',
cachedMediaUrl: '/media/cache/profile_thumb/uploads/img/',
postedContentUrl: '/uploads/img/',
+25
View File
@@ -1,5 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.talentstube.com/Offre/152-animateur-des-relais-assistants-maternels-f-h</loc>
<lastmod>2021-06-28</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.talentstube.com/Offre/147-monteur-de-systemes-mecanises-h-f</loc>
<lastmod>2021-06-28</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.talentstube.com/Entreprise/33350-greenyard-frozen</loc>
<lastmod>2021-06-28</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.talentstube.com/Offre/149-commercial-b-to-b-f-h/</loc>
<lastmod>2021-05-17</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.talentstube.com/Offre/150-responsable-webmarketing-f-h/</loc>
<lastmod>2021-05-17</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.talentstube.com/Entreprise/33190-les-francas-doubs/</loc>
<lastmod>2021-04-26</lastmod>
+1
View File
@@ -54,6 +54,7 @@
"react-facebook-login": "^4.1.1",
"react-ga": "^2.5.7",
"react-google-recaptcha": "^2.0.1",
"react-helmet": "^6.1.0",
"react-html-parser": "^2.0.2",
"react-jss": "latest",
"react-moment": "^0.9.7",
+443
View File
@@ -0,0 +1,443 @@
import React, {Fragment} from 'react';
import {connect} from "react-redux";
import PropTypes from 'prop-types';
import _ from "lodash"
import {withStyles} from '@material-ui/core/styles';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import {TextField, Button, Typography, Grid, Hidden} from '@material-ui/core';
import SwipeableViews from 'react-swipeable-views';
import Snack from '../components/atoms/snack'
import Loader from '../components/templates/loader'
import LayoutCandidature from '../components/templates/LayoutCandidature';
import CandidatureDetail from '../components/organisms/AnswerDetail'
import OffreDetail from '../components/organisms/OffreDetail'
import Chat from '../components/organisms/Chat'
import AppBar from '@material-ui/core/AppBar';
import {AnswersSelector} from '../reducers/answers'
import {fetchAnswerRequest} from '../actions/answer'
import Head from 'next/head'
import Chip from '@material-ui/core/Chip';
import getConfig from 'next/config'
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import ButtonBase from '@material-ui/core/ButtonBase';
const {publicRuntimeConfig} = getConfig()
const styles = theme => ({
root: {
position: 'relative',
textAlign: 'center',
paddingTop: theme.spacing(20),
justifyContent: 'center'
},
container: {
// display: 'flex',
// flexDirection: 'column',
height: '100%'
},
userDataContainer: {
// display: 'flex',
padding: theme.spacing(2) + 'px ',
[theme.breakpoints.up('md')]: {
padding: theme.spacing(2) + 'px 18vw',
},
},
userTextContainer: {
// display: 'flex',
// flexDirection: 'column',
paddingLeft: theme.spacing(2)
},
AppBar: {
top: '64px',
position: 'fixed'
},
SwipeableViews: {
paddingTop: '64px'
},
tab: {
'& span.MuiTab-wrapper': {
fontSize: '1.1em',
fontWeight: '300',
textTransform: 'none'
}
},
title: {
fontSize: '1em',
fontWeight: '500'
},
titleBorder: {
'&:after': {
content: '""',
width: '15px',
borderBottom: 'solid 2px',
borderColor: theme.palette.primary.main + '!important',
// display: 'flex'
}
},
userTextName: {
fontWeight: '500',
fontSize: '1em'
},
userTextDate: {
fontWeight: '500',
fontSize: '0.9em'
},
texteInfo:{
fontWeight: '300',
fontSize: '0.9em'
},
userAvatar: {
maxWidth: '104px',
},
menuLogo: {
cursor: 'pointer',
[
theme
.breakpoints
.down('md')
]: {
width: '200px'
},
[
theme
.breakpoints
.down('sm')
]: {
width: '130px'
}
},
information: {
padding: "1em",
width: "100%",
backgroundColor: theme.palette.secondary.main,
borderRadius: "5px",
marginBottom: "30px",
borderColor: "1px solid #E5E5E6"
},
grille: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
paddingLeft : theme.spacing(4),
marginBottom: "30px",
borderRadius: "5px",
border: "1px solid #1E2327",
color: theme.palette.primary.dark
},
menuLien: {
fontSize: "1em",
textTransform: "uppercase",
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
color: theme.palette.primary.dark,
textDecoration: "none",
'&:hover': {
color: theme.palette.primary.dark
},
'&:active': {
color: theme.palette.primary.dark
},
'&:visited': {
color: theme.palette.primary.dark
}
},
grilleGauche: {
textAlign: "center"
},
grilleDroite: {
textAlign: "center"
},
grilleBas: {
backgroundColor: theme.palette.secondary.dark
},
chip: {
marginTop: "10px",
backgroundColor: "#E7F3FF",
color: theme.palette.primary.dark
},
icon: {
color: theme.palette.secondary.dark
}
});
function TabContainer({children, dir}) {
return (
<Typography
component="div"
dir={dir}
style={{
padding: 8 * 3
}}>
{children}
</Typography>
);
}
const status = new Map([
["A_TRAITER"
, "Envoyée"]
,
["CONTACTE"
, "En cours de traitement"]
,
["ENTRETIEN"
, "En cours de traitement"]
,
["REFUSE"
, "Refusée"]
,
["EMBAUCHE"
, "Embauchée"]
,
["EXPIRED"
, "Expirée"]
,
[""
, "Envoyée"]
,
["Null"
, "Envoyée"]
,
])
class Candidature extends React.Component {
state = {
data: {},
errors: {},
loading: true,
tabIndex: 0,
openSnack: false
}
static getInitialProps(context) {
const {id} = context.query
return {
id: id * 1
}
}
componentDidMount() {
this
.props
.fetchAnswerRequest(this.props.id)
}
UNSAFE_componentWillReceiveProps(nextProps) {
this.setState({loading: nextProps.answer.loading})
}
componentWillUnmount() {}
handleChange = (event, newValue) => {
this.setState({tabIndex: newValue});
}
handleChangeIndex = (index) => {
this.setState({tabIndex: index});
}
render() {
const {classes} = this.props;
const {data, errors, loading, openSnack} = this.state;
console.log("test");
const logoUrl = (this.props.answer.ad
? (this.props.answer.ad.company.logo
? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + this.props.answer.ad.company.logo
: publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg")
: this.props.answer.company
? publicRuntimeConfig.symphonyUrl + publicRuntimeConfig.cachedMediaUrl + this.props.answer.company.logo
: publicRuntimeConfig.symphonyUrl + "/img/default_picture_svg")
const nomCompany = (this.props.answer.ad
? (this.props.answer.ad.company.brand_name
? this.props.answer.ad.company.brand_name
: "")
: this.props.answer.company
? this.props.answer.company.brand_name
: "")
const nomAd = (this.props.answer.ad
? (this.props.answer.ad.title
? this.props.answer.ad.title
: "Candidature spontanée")
: "Candidature spontanée")
//L'entreprise {nomCompany} étudie actuellement votre candidature
const infos = new Map([
[
"A_TRAITER", "Votre candidature a bien été envoyée à lentreprise "+nomCompany
],
[
"CONTACTE", "L'entreprise "+nomCompany+" étudie actuellement votre candidature"
],
[
"ENTRETIEN", "L'entreprise "+nomCompany+" étudie actuellement votre candidature"
],
[
"REFUSE", "Votre candidature a été refusée par lentreprise "+nomCompany+"."
],
[
"EMBAUCHE", "Votre candidature a été acceptée par lentreprise "+nomCompany+"."
],
[
"EXPIRED", "Expirée"
],
[
"", "Envoyée"
],
["Null", "Envoyée"]
])
//brand_name
return (
<LayoutCandidature>
<Head>
<title key="title">Candidature</title>
<meta name="robots" content="noindex, nofollow"></meta>
</Head>
<Fragment>
<div className={classes.container}>
{/* {!!errors && (<div className="alert alert-danger">{errors && errors.message}</div> )} */}
{loading && (<Loader/>)}
{!loading && (
<Fragment>
<AppBar color="default" className={classes.AppBar}>
<Tabs
value={this.state.tabIndex}
onChange={this.handleChange}
indicatorColor="primary"
variant="fullWidth">
<Tab label="Candidature" className={classes.tab}/>
<Tab label="Messagerie" className={classes.tab}/>
<Tab label="Offre d'emploi" className={classes.tab}/>
</Tabs>
</AppBar>
<SwipeableViews
axis={'x'}
index={this.state.tabIndex}
onChangeIndex={() => this.handleChangeIndex()}
className={classes.SwipeableViews}>
<TabContainer dir={'x'}>
<Fragment>
<section className={classes.userDataContainer}>
<Grid container spacing={2} className={classes.grille}>
<Grid item>
<ButtonBase className={classes.image}>
<img alt="talents-tube" src={logoUrl} className={classes.userAvatar}/>
</ButtonBase>
</Grid>
<Grid item lg={12} xl container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xl>
<Typography gutterBottom variant="subtitle1">
{(this.props.answer.ad
? (this.props.answer.ad.company.brand_name
? this.props.answer.ad.company.brand_name
: "")
: this.props.answer.company.brand_name)}
</Typography>
<Typography variant="body2" gutterBottom>
{this.props.answer.ad
? (this.props.answer.ad.title
? this.props.answer.ad.title
: "Candidature spontanée")
: "Candidature spontanée"}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid container spacing={2} className={classes.grille}>
<Grid container >
<Grid item>
<Typography gutterBottom className={classes.userTextDate}>
Envoyé le :
</Typography>
</Grid>
<Grid item xs={12} sm container>
<Typography gutterBottom className={classes.texteInfo}>
{(new Date(this.props.answer.c_time)).toLocaleDateString("fr-FR")}
</Typography>
</Grid>
</Grid>
<Grid container spacing={2} >
<Grid item>
<Typography gutterBottom variant="subtitle1" className={classes.userTextDate}>
Statut :
</Typography>
</Grid>
<Grid item xl={12} xl >
<Grid xl={12} xl container>
<Typography gutterBottom className={classes.texteInfo}>
<Chip size="small" label={status.get(this.props.answer.status_reponse)? status.get(this.props.answer.status_reponse) : "Envoyée" } className={classes.chip} />
</Typography>
</Grid>
<Grid xl={12} xl container>
<Typography gutterBottom className={classes.texteInfo}>
{infos.get(this.props.answer.status_reponse)
? infos.get(this.props.answer.status_reponse)
: "L'entreprise "+nomCompany+" étudie actuellement votre candidature"}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item className={classes.grille} spacing={2}>
{this.props.answer.video && <CandidatureDetail {...this.props.answer}/>}
</Grid>
</section>
</Fragment>
</TabContainer>
<TabContainer dir={'x'}>
{this.props.answer.messages && <Chat answerId={this.props.answer.id} nomCompany={nomCompany} logoUrl={logoUrl} nomAd={nomAd}></Chat>}
</TabContainer>
<TabContainer dir={'x'}>
{this.props.answer.ad && <OffreDetail isCandidature='true' offre={this.props.answer.ad}/>}
</TabContainer>
</SwipeableViews>
</Fragment>
)}
</div>
<Snack
variant="error"
message={this.state.errors.message}
openSnack={this.state.openSnack}
onClose={this.handleClose}/>
</Fragment>
</LayoutCandidature>
);
}
}
function mapStateToProps(state) {
return {answer: state.answer, user: state.user}
}
Candidature.propTypes = {
classes: PropTypes.object.isRequired,
id: PropTypes.number
};
export default withStyles(styles)(connect(mapStateToProps, {fetchAnswerRequest})(Candidature))
+4 -4
View File
@@ -136,7 +136,7 @@ class Candidatures extends React.Component {
if(newValue==0){
document.location.href="/Candidatures";
}else if(newValue==1){
document.location.href="/profileStep";
document.location.href="/profil2";
}else if(newValue==2){
document.location.href="/Parametres";
}
@@ -230,7 +230,7 @@ class Candidatures extends React.Component {
<GridBouton item xs={12} sm={10} lg={10} >
<GridBouton container justify="center" spacing={4}>
<GridBouton key={0} item xs={12} sm={4} >
<Link href={"/profileStep#information"} >
<Link href={"/profil2#information"} >
<Paper className={classes.paper} elevation={0}>
<div className={classes.boutonAction}>
<div>
@@ -249,7 +249,7 @@ class Candidatures extends React.Component {
</Link>
</GridBouton>
<GridBouton key={1} item xs={12} sm={4}>
<Link href={"/profileStep#video"} >
<Link href={"/profil2#video"} >
<Paper className={classes.paper} elevation={0}>
<div className={classes.boutonAction}>
<div>
@@ -267,7 +267,7 @@ class Candidatures extends React.Component {
</Link>
</GridBouton>
<GridBouton key={2} item xs={12} sm={4}>
<Link href={"/profileStep#cv"} >
<Link href={"/profil2#cv"} >
<Paper className={classes.paper} elevation={0}>
<div className={classes.boutonAction}>
+1 -1
View File
@@ -76,7 +76,7 @@ class MentionsLegales extends Component {
`
TALENTS TUBE est joignable :
- Par internet : via le formulaire de contact sur le site ` }<a href="http://blog.talentstube.com" className={classes.link} target="_blank">blog.talentstube.com</a>{`;
- Par téléphone au 02 30 05 06 31, du lundi au vendredi de 9 h à 18 h;
- Par téléphone au 07 56 85 27 36, du lundi au vendredi de 9 h à 18 h;
- Par voie postale :
TALENTS TUBE
3 Rue Louis de Broglie
+2 -2
View File
@@ -73,8 +73,8 @@ class Player extends Component {
const urlEnv = process.env.NODE_ENV;
//pour la MEP
{/* A ENLEVER EN PROD */}
let nofollow = false;
urlEnv == "development" ? nofollow = true : nofollow = true;
let nofollow = true;
// urlEnv == "development" ? nofollow = true : nofollow = true;
console.log(id);
console.log(typeEntite);
+3 -3
View File
@@ -340,13 +340,13 @@ class Reponse extends React.Component {
return (
<LayoutBack text="Candidature" step={this.state.activeStep} openStudio={this.state.openStudio}>
<Head>
<title>Candidature vidéo</title>
<meta name="description" content="Talents tube, postulez en video." />
<title key="title">Candidature vidéo</title>
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
</Head>
{/* https://codesandbox.io/s/ii0us */}
<section className={classes.headerContainer}>
{ !!offre.company && (
+1 -1
View File
@@ -37,7 +37,7 @@ class MyDocument extends Document {
<link rel="stylesheet" type="text/css" charset="UTF-8" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" />
<link rel="stylesheet" type="text/css" href="/statique/css/autocomplete.css" />
<script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDYV8IJGtIoWLfXJQQvIuDQ88n2aEuRgpg&libraries=places"></script>
<script async type="text/javascript" src="/static/js/pwaInstaller.js" ></script>
{/* Global Site Tag (gtag.js) - Google Analytics */}
{/* <script
+2 -5
View File
@@ -443,7 +443,7 @@ class Index extends React.Component {
]}
/>
<div className={classes.wrap}>
{/* PARTIE DESKTOP */}
<Hidden smDown>
<header className={classes.headerTitre}>
<h1 className={classes.titreAccueil}>La rencontre doffres demploi et de candidatures en vidéo</h1>
@@ -523,9 +523,6 @@ class Index extends React.Component {
</Hidden>
</div>
<div className={classes.container}>
{/* <VideoSlider /> */}
<section className={classes.scrollerSection + ' ' + classes.scrollerSectionOffer}>
<div
className={classes.HorizontalScrollerOffre}
@@ -643,7 +640,7 @@ class Index extends React.Component {
</section>
<section className={classes.scrollerSection + ' ' + classes.scrollerSectionSlider}>
{/* PARTIE DEsktop */}
{/* PARTIE Desktop Slider des logos d'entreprises*/}
<Hidden smDown>
<Slider ref={slider => (this.slider = slider)} {...settings}>
<a href="/Entreprise/21247-lactalis-logistique-et-transports">
+80
View File
@@ -0,0 +1,80 @@
import React from 'react';
import {makeStyles} from '@material-ui/core/styles';
import Layout from "../components/templates/Layout";
import AccountProfile2 from "../components/organisms/AccountProfile2";
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">Profil 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 >
<AccountProfile2/>
</div>
</Layout>
);
}
+4 -2
View File
@@ -6,6 +6,7 @@ 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%'
@@ -56,7 +57,7 @@ export default function HorizontalNonLinearStepper() {
return (
<Layout>
<Head>
<title key="title">Profil Talents Tube</title>
<title key="title">Profil Talents Tube...</title>
<meta key="robots" name="robots" content="noindex, nofollow"></meta>
</Head>
<div >
@@ -71,9 +72,10 @@ export default function HorizontalNonLinearStepper() {
</AdBlockDetect>
</div>
<div >
<AccountProfile/>
</div>
</Layout>
);
}
}
+6
View File
@@ -147,6 +147,12 @@ app.prepare()
app.render(req, res, actualPage, queryParams)
})
server.get('/Answer/:id', (req, res) => {
const actualPage = '/Answer'
const queryParams = { id: req.params.id }
app.render(req, res, actualPage, queryParams)
})
server.get('/Offre/:id-:rest', (req, res) => {
const actualPage = '/Offre'
const queryParams = { id: req.params.id }
+1 -1
View File
@@ -17,7 +17,7 @@ Disallow: /Cgu
Disallow: /Confidentialite
Disallow: /Candidature
Disallow: /CandidatureValidation
Disallow: /profileStep
Disallow: /profil2
# Sitemap
Sitemap: https://www.talentstube.com/sitemap_local.xml`