Prechádzať zdrojové kódy

cleaver start mokup

amenpunk 3 rokov pred
rodič
commit
8091680dbe

+ 7 - 0
src/App.css

@@ -299,4 +299,11 @@
   align-content: space-around;
 }
 
+.quiz_title_text{
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: baseline !important;
+  justify-content: flex-start;
+}
 

+ 74 - 0
src/Components/Test/Cleaver/Question.jsx

@@ -0,0 +1,74 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import Card from '@mui/material/Card';
+import CardActions from '@mui/material/CardActions';
+import CardContent from '@mui/material/CardContent';
+import Button from '@mui/material/Button';
+import Typography from '@mui/material/Typography';
+import Avatar from '@mui/material/Avatar';
+// import Stack from '@mui/material/Stack';
+// import Radio from '@mui/material/Radio';
+import RadioGroup from '@mui/material/RadioGroup';
+import FormControlLabel from '@mui/material/FormControlLabel';
+import FormControl from '@mui/material/FormControl';
+import FormLabel from '@mui/material/FormLabel';
+import Checkbox from '@mui/material/Checkbox';
+import { deepPurple } from '@mui/material/colors';
+const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
+
+
+function Radio() {
+  return(
+    <div>
+    <Checkbox {...label} defaultChecked />
+      <Checkbox {...label} />
+    </div>
+  )
+}
+
+
+function Response ({resp}) {
+  return (
+    <FormControl>
+      <RadioGroup
+        aria-labelledby="demo-radio-buttons-group-label"
+        defaultValue="female"
+        name="radio-buttons-group"
+      >
+        {
+        resp.map(a => <FormControlLabel value="female" control={<Radio />} label={a.nombre} />)
+        }
+      </RadioGroup>
+    </FormControl>
+  )
+}
+
+export function Question({ quiz }) {
+  let { instrucciondepregunta, id, respuestas } = quiz
+  return (
+    <Card sx={{ minWidth: 275, margin: 5 }}>
+      <CardContent>
+
+        <Typography sx={{ fontSize: 17 }} color="text.secondary" gutterBottom>
+          <div className="quiz_title_text">
+            <Avatar sx={{ bgcolor: deepPurple[500] }}>{id}</Avatar>
+            <p style={{ paddingLeft: 15 }}>
+              {instrucciondepregunta}
+            </p>
+          </div>
+        </Typography>
+
+
+        <Typography variant="body2">
+          <Response resp={respuestas}/>
+        </Typography>
+
+      </CardContent>
+
+      <CardActions>
+        <Button size="small">Learn More</Button>
+      </CardActions>
+
+    </Card>
+  );
+}

+ 85 - 0
src/Components/Test/Cleaver/Response.jsx

@@ -0,0 +1,85 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import FormLabel from '@mui/material/FormLabel';
+import FormControl from '@mui/material/FormControl';
+import FormGroup from '@mui/material/FormGroup';
+import FormControlLabel from '@mui/material/FormControlLabel';
+import FormHelperText from '@mui/material/FormHelperText';
+import Checkbox from '@mui/material/Checkbox';
+
+export function Radios() {
+  const [state, setState] = React.useState({
+    gilad: true,
+    jason: false,
+    antoine: false,
+  });
+
+  const handleChange = (event) => {
+    setState({
+      ...state,
+      [event.target.name]: event.target.checked,
+    });
+  };
+
+  const { gilad, jason, antoine } = state;
+  const error = [gilad, jason, antoine].filter((v) => v).length !== 2;
+
+  return (
+    <Box sx={{ display: 'flex' }}>
+      <FormControl sx={{ m: 3 }} component="fieldset" variant="standard">
+        <FormLabel component="legend">Assign responsibility</FormLabel>
+        <FormGroup>
+          <FormControlLabel
+            control={
+              <Checkbox checked={gilad} onChange={handleChange} name="gilad" />
+            }
+            label="Gilad Gray"
+          />
+          <FormControlLabel
+            control={
+              <Checkbox checked={jason} onChange={handleChange} name="jason" />
+            }
+            label="Jason Killian"
+          />
+          <FormControlLabel
+            control={
+              <Checkbox checked={antoine} onChange={handleChange} name="antoine" />
+            }
+            label="Antoine Llorca"
+          />
+        </FormGroup>
+        <FormHelperText>Be careful</FormHelperText>
+      </FormControl>
+      <FormControl
+        required
+        error={error}
+        component="fieldset"
+        sx={{ m: 3 }}
+        variant="standard"
+      >
+        <FormLabel component="legend">Pick two</FormLabel>
+        <FormGroup>
+          <FormControlLabel
+            control={
+              <Checkbox checked={gilad} onChange={handleChange} name="gilad" />
+            }
+            label="Gilad Gray"
+          />
+          <FormControlLabel
+            control={
+              <Checkbox checked={jason} onChange={handleChange} name="jason" />
+            }
+            label="Jason Killian"
+          />
+          <FormControlLabel
+            control={
+              <Checkbox checked={antoine} onChange={handleChange} name="antoine" />
+            }
+            label="Antoine Llorca"
+          />
+        </FormGroup>
+        <FormHelperText>You can display an error</FormHelperText>
+      </FormControl>
+    </Box>
+  );
+}

+ 163 - 159
src/Pages/Logincs.jsx

@@ -4,9 +4,9 @@ import { useNavigate } from 'react-router-dom'
 import jwt_decode from "jwt-decode";
 
 import {
-    Paper, Box, Grid, Typography,
-    TextField, Button, Avatar,
-    Backdrop, CircularProgress,
+  Paper, Box, Grid, Typography,
+  TextField, Button, Avatar,
+  Backdrop, CircularProgress,
 } from '@mui/material'
 
 import { createTheme, ThemeProvider } from '@mui/material/styles';
@@ -23,166 +23,170 @@ import * as Yup from 'yup';
 import { Service } from '../Utils/HTTP.js'
 
 const LoginSchema = Yup.object().shape({
-    email: Yup
-        .string()
-        .email('El correo debe ser válido')
-        .required('El correo o usuario es requerido'),
-    password: Yup
-        .string()
-        .required('El campo contraseña es requerido')
-        .min(5, 'La contraseña debe contener mínimo 5 caracteres')
+  email: Yup
+    .string()
+    .email('El correo debe ser válido')
+    .required('El correo o usuario es requerido'),
+  password: Yup
+    .string()
+    .required('El campo contraseña es requerido')
+    .min(5, 'La contraseña debe contener mínimo 5 caracteres')
 })
 
 const theme = createTheme();
 
 export function LoginCs() {
 
-    let auth = useAuth();
-    let navigate = useNavigate()
-
-    const [open, setOpen] = React.useState(false);
-    const handleClose = () => false
-
-    const formik = useFormik({
-        initialValues: {
-            email: '',
-            password: '',
-        },
-        validationSchema: LoginSchema,
-        onSubmit: async (values) => {
-
-            //
-            // QW5hbGlzdGEgZGUgY29tcHJhcw==
-            //
-            
-            let { email, password } = values
-            setOpen(true)
-
-            let request = new Service(`/user?user=${email}&password=${password}&typeusr=iscandidato`)
-            request
-                .post({})
-                .then(response => {
-
-                    console.log("Service Response :: ", response)
-                    let { token, nombre, apelidos, id : pass_id} = response;
-                    toast.success(`Bienvenido ${nombre} ${apelidos}!!`)
-                    token = token.replace("Bearer ", "")
-                    console.log(token);
-
-                    // let { exp } = jwt_decode(token);
-                    let body_token = jwt_decode(token);
-                    body_token['pass'] = password;
-                    body_token['passid'] = pass_id;
-                    console.log("BODY TOKEN: ", body_token)
-                    // let timestamp = exp * 1000;
-                    // let restante = timestamp - Date.now();
-
-                    // setTimeout(() => alert("Token Expirado"), restante)
-                    auth.setProfile({
-                        email, password
-                    })
-                    auth.setRole(body_token)
-
-                    setTimeout(() => {
-                        setOpen(false)
-                        auth.login(token)
-                    }, 2000)
-
-                })
-                .catch(err => {
-                    setOpen(false)
-                    toast.error("Ups! usuario o contraseña incorrectos")
-                    console.log("ERROR ", err)
-                })
-
-        },
-    });
-
-    React.useEffect(() => {
-        if(auth.isLogged()){
-            return navigate('/user/home')
-        }
-    }, [auth,navigate])
-
-    return (
-        <ThemeProvider theme={theme}>
-            <Grid container component="main" sx={{ height: '100vh' }}>
-                <Grid item xs={12} sm={12} md={12} component={Paper} elevation={6} square>
-
-                    <Box
-                        sx={{
-                            my: 8,
-                            mx: 4,
-                            marginTop:25,
-                            display: 'flex',
-                            flexDirection: 'column',
-                            // alignItems:true?'flex-start': 'center',
-                            alignItems:'center'
-                        }}
-                    >
-                        <Avatar sx={{ m: 1, bgcolor: 'var(--second)' }}>
-                            <PersonIcon />
-                        </Avatar>
-                        <Typography component="h1" variant="h5">
-                            Ingresar
-                        </Typography>
-
-                        <Box component="form" noValidate onSubmit={formik.handleSubmit} sx={{ mt: 1 }}>
-                            <TextField
-                                value={formik.values.email}
-                                onChange={formik.handleChange}
-                                error={formik.touched.email && Boolean(formik.errors.email)}
-                                helperText={formik.touched.email && formik.errors.email}
-                                margin="normal"
-                                required
-                                fullWidth
-                                id="email"
-                                name="email"
-                                label="Correo Electrónico"
-                                autoComplete="email"
-                                autoFocus
-                            />
-                            <TextField
-                                value={formik.values.password}
-                                onChange={formik.handleChange}
-                                error={formik.touched.password && Boolean(formik.errors.password)}
-                                helperText={formik.touched.password && formik.errors.password}
-                                margin="normal"
-                                required
-                                fullWidth
-                                label="Contraseña"
-                                name="password"
-                                type="password"
-                                id="password"
-                                autoComplete="current-password"
-                            />
-                            <Button
-                                id="login_btn_fn"
-                                type="submit"
-                                fullWidth
-                                variant="contained"
-                                sx={{ mt: 3, mb: 2, bgcolor: 'var(--second)' }}
-                            >
-                                Ingresar
-                            </Button>
-                            <Copyright sx={{ mt: 5 }} />
-                        </Box>
-                    </Box>
-                </Grid>
-            </Grid>
-            <Toaster
-                position="top-left"
-                reverseOrder={false}
-            />
-            <Backdrop
-                sx={{ color: '#fd4b4b', zIndex: (theme) => theme.zIndex.drawer + 1 }}
-                open={open}
-                onClick={handleClose}
-            >
-                <CircularProgress color="inherit" />
-            </Backdrop>
-
-        </ThemeProvider>
-
-    );
+  let auth = useAuth();
+  let navigate = useNavigate()
+
+  const [open, setOpen] = React.useState(false);
+  const handleClose = () => false
+
+  const formik = useFormik({
+    initialValues: {
+      email: '',
+      password: '',
+    },
+    validationSchema: LoginSchema,
+    onSubmit: async (values) => {
+
+      //
+      // QW5hbGlzdGEgZGUgY29tcHJhcw==
+      //
+
+      let { email, password } = values
+      setOpen(true)
+
+      let request = new Service(`/user?user=${email}&password=${password}&typeusr=iscandidato`)
+      request
+        .post({})
+        .then(response => {
+
+          console.log("Service Response :: ", response)
+          let { token, nombre, apelidos, id: pass_id } = response;
+          toast.success(`Bienvenido ${nombre} ${apelidos}!!`)
+          token = token.replace("Bearer ", "")
+          console.log(token);
+
+          // let { exp } = jwt_decode(token);
+          let body_token = jwt_decode(token);
+          body_token['pass'] = password;
+          body_token['passid'] = pass_id;
+          console.log("BODY TOKEN: ", body_token)
+          // let timestamp = exp * 1000;
+          // let restante = timestamp - Date.now();
+
+          // setTimeout(() => alert("Token Expirado"), restante)
+          auth.setProfile({
+            email,
+            password,
+            passid: pass_id,
+            pass: password,
+            assingid: 'ok'
+          })
+          auth.setRole(body_token)
+
+          setTimeout(() => {
+            setOpen(false)
+            auth.login(token)
+          }, 2000)
+
+        })
+        .catch(err => {
+          setOpen(false)
+          toast.error("Ups! usuario o contraseña incorrectos")
+          console.log("ERROR ", err)
+        })
+
+    },
+  });
+
+  React.useEffect(() => {
+    if (auth.isLogged()) {
+      return navigate('/user/home')
+    }
+  }, [auth, navigate])
+
+  return (
+    <ThemeProvider theme={theme}>
+      <Grid container component="main" sx={{ height: '100vh' }}>
+        <Grid item xs={12} sm={12} md={12} component={Paper} elevation={6} square>
+
+          <Box
+            sx={{
+              my: 8,
+              mx: 4,
+              marginTop: 25,
+              display: 'flex',
+              flexDirection: 'column',
+              // alignItems:true?'flex-start': 'center',
+              alignItems: 'center'
+            }}
+          >
+            <Avatar sx={{ m: 1, bgcolor: 'var(--second)' }}>
+              <PersonIcon />
+            </Avatar>
+            <Typography component="h1" variant="h5">
+              Ingresar
+            </Typography>
+
+            <Box component="form" noValidate onSubmit={formik.handleSubmit} sx={{ mt: 1 }}>
+              <TextField
+                value={formik.values.email}
+                onChange={formik.handleChange}
+                error={formik.touched.email && Boolean(formik.errors.email)}
+                helperText={formik.touched.email && formik.errors.email}
+                margin="normal"
+                required
+                fullWidth
+                id="email"
+                name="email"
+                label="Correo Electrónico"
+                autoComplete="email"
+                autoFocus
+              />
+              <TextField
+                value={formik.values.password}
+                onChange={formik.handleChange}
+                error={formik.touched.password && Boolean(formik.errors.password)}
+                helperText={formik.touched.password && formik.errors.password}
+                margin="normal"
+                required
+                fullWidth
+                label="Contraseña"
+                name="password"
+                type="password"
+                id="password"
+                autoComplete="current-password"
+              />
+              <Button
+                id="login_btn_fn"
+                type="submit"
+                fullWidth
+                variant="contained"
+                sx={{ mt: 3, mb: 2, bgcolor: 'var(--second)' }}
+              >
+                Ingresar
+              </Button>
+              <Copyright sx={{ mt: 5 }} />
+            </Box>
+          </Box>
+        </Grid>
+      </Grid>
+      <Toaster
+        position="top-left"
+        reverseOrder={false}
+      />
+      <Backdrop
+        sx={{ color: '#fd4b4b', zIndex: (theme) => theme.zIndex.drawer + 1 }}
+        open={open}
+        onClick={handleClose}
+      >
+        <CircularProgress color="inherit" />
+      </Backdrop>
+
+    </ThemeProvider>
+
+  );
 }

+ 42 - 25
src/Pages/Prueba.jsx

@@ -1,49 +1,62 @@
 import React, { useMemo, useState } from 'react';
-import { useParams } from 'react-router-dom'
 import { Service } from '../Utils/HTTP'
-import useAuth from '../Auth/useAuth.js';
 import { Box, Paper, Divider, Typography, Button } from '@mui/material'
 
+import toast, { Toaster } from 'react-hot-toast';
+import { useParams } from 'react-router-dom'
+import useAuth from '../Auth/useAuth.js';
+import { Cleaver } from './Pruebas/Cleaver';
+
 export function Prueba() {
 
   let { id } = useParams();
   let auth = useAuth();
-  let token = useMemo(() => auth.getToken())
+  let token = useMemo(() => auth.getToken(), [auth])
   let [data, setData] = useState({});
+  // let profile = auth.getProfile();
+  let [profile, setProfile] = useState(auth.getProfile)
 
   useState(() => {
     let rest = new Service(`/prueba/findid/${id}`)
-    rest.get(token)
-      .then(resp => setData(resp.data))
-      .catch( _e => setData({}))
+    rest.get(token.toString())
+      .then(resp => { 
+          setData(resp.data)
+        })
+      .catch(_e => setData({}))
   }, [id])
 
   const CreateAssign = () => {
+
     let now = new Date().toISOString();
-    let user = auth.getProfile();
     let body = {
       "id": -1,
       "fechaasignacio": now,
-      "fechafinexamen": now, 
+      "fechafinexamen": now,
       "estado": "1",
-      "score" : "0",
-      "mensaje" : "0",
-      "mensaje2" : "0",
-      "idcontrasenia": user.passid,
+      "score": "0",
+      "mensaje": "0",
+      "mensaje2": "0",
+      "idcontrasenia": profile.passid,
       "nombre": "assing CLEVAERR"
 
     }
-    let rest = new Service("/prueba/asignacion");
-    rest.postQuery(body,token)
-      .then( ({ data: resp }) => {
-        let { id : assingid } = resp
-        let profile = auth.getProfile();
 
-        auth.setProfile({
-          ...profile, assingid
-        })
+    let rest = new Service("/prueba/asignacion");
+    rest.postQuery(body, token)
+      .then(({ data: resp }) => {
+        let { id: assingid } = resp
+        toast.success("Asignación creada: ", assingid)
+        let new_profile = { ...profile, assingid }
+        auth.setProfile(new_profile)
+        setProfile(new_profile)
       })
-      .catch(console.log)
+      .catch(() => {
+        toast.error("Error al crear la asignación")
+      })
+  }
+
+  if(profile.assingid){
+    return <Cleaver/>
   }
 
   return (
@@ -51,13 +64,17 @@ export function Prueba() {
       <div className="main">
         <Box >
           <Paper className="prueba_body" elevation={1}>
-            <h1>{data.nombre}</h1>
-            <Divider/>
-            <Typography style={{marginTop:15, textAlign: 'center'}}>{data.decription}</Typography>
-            <Divider style={{marginTop:15}}/>
+            <h1>{data?.nombre}</h1>
+            <Divider />
+            <Typography style={{ marginTop: 15, textAlign: 'center' }}>{data?.decription}</Typography>
+            <Divider style={{ marginTop: 15 }} />
             <Button onClick={CreateAssign}>Inicar Prueba</Button>
           </Paper>
         </Box>
+        <Toaster
+          position="top-left"
+          reverseOrder={false}
+        />
       </div>
     </div>
   );

+ 71 - 0
src/Pages/Pruebas/Cleaver.jsx

@@ -0,0 +1,71 @@
+import React, { useMemo} from 'react'
+import {
+  Box, 
+  // Paper,
+  LinearProgress
+} from '@mui/material'
+
+import { Service } from '../../Utils/HTTP'
+import useAuth from '../../Auth/useAuth.js';
+import {Question} from '../../Components/Test/Cleaver/Question.jsx'
+
+
+export function Cleaver() {
+
+  let auth = useAuth();
+  let token = useMemo(() => auth.getToken(), [auth])
+
+  const [progress, setProgress] = React.useState(0);
+  const [questions, setQuestions] = React.useState([]);
+  const [buffer, setBuffer] = React.useState(10);
+
+  const progressRef = React.useRef(() => {});
+
+  React.useEffect(() => {
+
+    let rest = new Service(`/prueba/findid/1`)
+    rest.get(token.toString())
+      .then(({data}) => { 
+        console.log("RESP: ", data)
+        setQuestions(data.questions)
+      })
+      .catch( e => console.log("ERROR: ", e))
+
+    const timer = setInterval(() => {
+      progressRef.current();
+    }, 500);
+
+    return () => {
+      clearInterval(timer);
+    };
+  }, []);
+
+
+  React.useEffect(() => {
+    progressRef.current = () => {
+      if (progress > 100) {
+        setProgress(0);
+        setBuffer(10);
+      } else {
+        const diff = Math.random() * 10;
+        const diff2 = Math.random() * 10;
+        setProgress(progress + diff);
+        setBuffer(progress + diff + diff2);
+      }
+    };
+  });
+
+  return (
+    <div className="content-section">
+      <div className="main">
+        <Box sx={{ width: '100%' , magin : 5}}>
+          <LinearProgress style={{ margin : 5}} variant="buffer" value={progress} valueBuffer={buffer} />
+        </Box>
+        {
+        questions.map( e => (<Question key={e.id} quiz={e}/>) )
+      }
+      </div>
+    </div>
+  )
+
+}