-
-
-
+
diff --git a/uniEmpleos/src/pages/Home/Home.module.css b/uniEmpleos/src/pages/Home/Home.module.css
index 9b7c6d20..9ad57150 100644
--- a/uniEmpleos/src/pages/Home/Home.module.css
+++ b/uniEmpleos/src/pages/Home/Home.module.css
@@ -2,6 +2,7 @@
display: flex;
flex-direction: column;
width: 100%;
+ height: 100vh;
background-color: #f5f5f5;
}
@@ -10,7 +11,6 @@
flex-direction: column;
justify-content: center;
align-items: center;
- height: 100%;
width: 100%;
background-color: transparent;
}
@@ -95,7 +95,7 @@ span.text{
display: flex;
flex-direction: column;
width: 100%;
- background-color: #f5f5f5;
+ background-color: #fff;
}
.button{
@@ -109,18 +109,14 @@ span.text{
.info{
flex-direction: column;
+ gap:40px;
}
- .wave, .waveup{
- height: 150px;
-
.infobutton{
width: 100%;
}
.button{
- flex-direction: column;
align-items: center;
}
}
-}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/Login/Login.jsx b/uniEmpleos/src/pages/Login/Login.jsx
index c454a04f..59883e4d 100644
--- a/uniEmpleos/src/pages/Login/Login.jsx
+++ b/uniEmpleos/src/pages/Login/Login.jsx
@@ -44,7 +44,7 @@ const LogIn = () => {
if (role === "student") {
navigate("/profile")
} else if (role === "enterprise") {
- navigate("/profilecompany")
+ navigate("/postulacionempresa")
} else if (role === "admin") {
navigate("/profileadmin")
}
diff --git a/uniEmpleos/src/pages/OfferDetails/OfferDetails.jsx b/uniEmpleos/src/pages/OfferDetails/OfferDetails.jsx
index 9c9ef56f..04e69adb 100644
--- a/uniEmpleos/src/pages/OfferDetails/OfferDetails.jsx
+++ b/uniEmpleos/src/pages/OfferDetails/OfferDetails.jsx
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from "react"
+import Select from "react-select"
import { useStoreon } from "storeon/react"
import Joi from "joi"
import { useQuill } from "react-quilljs"
@@ -29,7 +30,7 @@ const OfferDetails = ({ id }) => {
const [salario, setSalario] = useState("")
const [puesto, setPuesto] = useState("")
const [detalles, setDetalles] = useState("")
- const [carrera, setCarrera] = useState([])
+ const [carrera, setCarrera] = useState("")
const [carreras, setCarreras] = useState([])
const { quill, quillRef } = useQuill()
const [warning, setWarning] = useState(false)
@@ -63,13 +64,16 @@ const OfferDetails = ({ id }) => {
setSalario(dataa[i].salario)
setRequisitos(dataa[i].requisitos)
setDetalles(dataa[i].descripcion)
- if (dataa[i].id_carreras !== null) {
- setCarrera(dataa[i].id_carreras.map((num) => num.toString()))
+ if (
+ dataa[i].id_carreras !== null &&
+ dataa[i].id_carreras.length > 0
+ ) {
+ setCarrera(dataa[i].id_carreras[0].toString()) // usar el primer elemento del array
} else {
- setCarrera(["1"])
+ setCarrera("1") // o cualquier valor predeterminado que desees
}
} else {
- console.log("not changing", id)
+ console.log(carrera)
}
}
}
@@ -92,7 +96,7 @@ const OfferDetails = ({ id }) => {
descripcion: details,
requisitos,
salario: parseFloat(salario),
- id_carreras: carrera,
+ id_carreras: [carrera],
})
if (apiResponse.status === 200) {
navigate("/postulacionempresa")
@@ -118,10 +122,7 @@ const OfferDetails = ({ id }) => {
}
const handleCarrera = (e) => {
- const selectedOptions = Array.from(e.target.selectedOptions).map(
- (option) => option.value
- )
- setCarrera(selectedOptions)
+ setCarrera(e.value.toString())
}
const handleInputsValue = (e) => {
@@ -214,9 +215,29 @@ const OfferDetails = ({ id }) => {
Carrera
- ({
+ ...baseStyles,
+ borderColor: state.isFocused ? "#a08ae5" : "grey",
+ color: "black",
+ }),
+ option: (baseStyles) => ({
+ ...baseStyles,
+ color: "black",
+ }),
+ }}
+ name="carrera"
+ theme={(theme) => ({
+ ...theme,
+ colors: {
+ ...theme.colors,
+ primary25: "#94bd0f",
+ primary: "#a08ae5",
+ },
+ })}
+ options={carreras}
+ value={carreras.find((option) => option.value === carrera)}
onChange={handleCarrera}
/>
diff --git a/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.jsx b/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.jsx
new file mode 100644
index 00000000..67aad51d
--- /dev/null
+++ b/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.jsx
@@ -0,0 +1,86 @@
+import React, { useEffect, useState } from "react"
+import PropTypes from "prop-types"
+import useApi from "../../Hooks/useApi"
+import InfoStudent from "../../components/InfoStudent/InfoStudent"
+import style from "./PostulantesPage.module.css"
+import Popup from "../../components/Popup/Popup"
+import { Header } from "../../components/Header/Header"
+import { navigate } from "../../store"
+import API_URL from "../../api"
+import fotoPFP from "/images/pfp.svg"
+import Loader from "../../components/Loader/Loader"
+
+const PostulantesPage = ({ id }) => {
+ const api = useApi()
+ const [response, setResponse] = useState([])
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [loading, setLoading] = useState(false)
+
+ const obtainPostulantes = async () => {
+ setLoading(true)
+ const datos = await api.handleRequest("POST", "/offers/applicants", {
+ id_oferta: parseInt(id, 10),
+ })
+ if (datos.status === 200) {
+ setResponse(datos)
+ } else {
+ setTypeError(1)
+ setError("Error al obtener los postulantes")
+ setWarning(true)
+ }
+ setLoading(false)
+ }
+
+ useEffect(() => {
+ obtainPostulantes()
+ }, [])
+
+ const handleClickUsuario = (idUsuario) => {
+ navigate(`/publicprofile/${idUsuario}-${id}`)
+ }
+
+ return (
+
+
+
setWarning(false)}
+ />
+ Postulantes
+ {loading ? (
+
+ ) : (
+
+ {response.data ? (
+ response.data.map((postulante) => (
+ handleClickUsuario(postulante.id_estudiante)}
+ />
+ ))
+ ) : (
+ No hay postulantes
+ )}
+
+ )}
+
+ )
+}
+
+PostulantesPage.propTypes = {
+ id: PropTypes.string.isRequired,
+}
+
+export default PostulantesPage
diff --git a/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.module.css b/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.module.css
new file mode 100644
index 00000000..276af203
--- /dev/null
+++ b/uniEmpleos/src/pages/PostulantesPage/PostulantesPage.module.css
@@ -0,0 +1,27 @@
+.mainContainer {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+}
+
+.mainContainer h1{
+ font-weight: 700;
+ margin-bottom: 20px;
+ color: #333333;
+ text-align: left;
+ padding: 20px;
+}
+
+.infoStudentContainer {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: start;
+ gap: 30px;
+ margin-top: 20px;
+ padding: 10px;
+}
+
+.sinPostulantes {
+ color: #000;
+}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.jsx b/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.jsx
index 291c79b0..d6768061 100644
--- a/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.jsx
+++ b/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.jsx
@@ -7,6 +7,8 @@ import InfoTab from "../../components/InfoTab/InfoTab"
import { Header } from "../../components/Header/Header"
import { navigate } from "../../store"
import useApi from "../../Hooks/useApi"
+import Popup from "../../components/Popup/Popup"
+import Loader from "../../components/Loader/Loader"
const schema = Joi.object({
token: Joi.string().required(),
@@ -23,17 +25,24 @@ const PostulationsEmpresa = () => {
const { user } = useStoreon("user")
const api = useApi()
+ const obtainPostulantes = useApi()
const [dataa, setData] = useState([])
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [loading, setLoading] = useState(false)
useEffect(() => {
if (api.data) {
const { offers } = api.data
setData(offers)
}
+ setLoading(false)
}, [api.data])
useEffect(() => {
+ setLoading(true)
api.handleRequest("POST", "/offers/company", {
id_empresa: user.id_user,
})
@@ -48,13 +57,39 @@ const PostulationsEmpresa = () => {
)
}
+ const handleVerPostulantes = async (id) => {
+ const datos = await obtainPostulantes.handleRequest(
+ "POST",
+ "/offers/applicants",
+ {
+ id_oferta: parseInt(id, 10),
+ }
+ )
+ if (datos.data) {
+ navigate(`/postulantes/${id}`)
+ } else {
+ setTypeError(2)
+ setError("La oferta no tiene postulantes")
+ setWarning(true)
+ }
+ }
+
return (
-
- {api.data ? (
+
+
setWarning(false)}
+ />
+ {loading ? (
+
+ ) : dataa.length > 0 ? (
{dataa.map((postulation) => (
{
onClick={() => {
saveidlocalstorage(postulation.id_oferta)
}}
+ verPostulantes={() => {
+ handleVerPostulantes(postulation.id_oferta)
+ }}
/>
))}
) : (
-
No tiene niguna oferta activa
+ No tiene niguna oferta activa
)}
diff --git a/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.module.css b/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.module.css
index eb911f5c..3ee94140 100644
--- a/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.module.css
+++ b/uniEmpleos/src/pages/PostulationsEmpresa/PostulationsEmpresa.module.css
@@ -1,7 +1,14 @@
.containerinfoprincipal{
display: flex;
flex-wrap: wrap;
- justify-content: center;
- gap: 20px;
+ justify-content: start;
+ gap: 30px;
margin-top: 20px;
+ padding: 10px;
+}
+
+@media screen and (max-width: 768px){
+ .containerinfoprincipal{
+ justify-content: center;
+ }
}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/PostulationsEstudentPage/PostulationsEstudent.jsx b/uniEmpleos/src/pages/PostulationsEstudentPage/PostulationsEstudent.jsx
index 1160e27a..d689e99a 100644
--- a/uniEmpleos/src/pages/PostulationsEstudentPage/PostulationsEstudent.jsx
+++ b/uniEmpleos/src/pages/PostulationsEstudentPage/PostulationsEstudent.jsx
@@ -1,6 +1,6 @@
-import react, { useState, useEffect } from "react"
-import useApi from "../../Hooks/useApi"
+import React, { useState, useEffect } from "react"
import { useStoreon } from "storeon/react"
+import useApi from "../../Hooks/useApi"
import Header from "../../components/Header/Header"
import InfoTab from "../../components/InfoTab/InfoTab"
import styles from "./PostulationsEstudent.module.css"
@@ -13,9 +13,17 @@ const PostulationsEstudent = () => {
const [typePopUp, setTypePopUp] = useState(1)
const [warning, setWarning] = useState(false)
const [error, setError] = useState("")
+ const [postulaciones, setPostulaciones] = useState([])
- const obtainPostulations = () => {
- api.handleRequest("GET", "/postulations/getFromStudent")
+ const obtainPostulations = async () => {
+ const datos = await api.handleRequest("GET", "/postulations/getFromStudent")
+ if (datos.status === 200) {
+ setPostulaciones(datos.data)
+ } else {
+ setTypePopUp(1)
+ setError("Error al obtener las postulaciones")
+ setWarning(true)
+ }
}
useEffect(() => {
@@ -23,13 +31,16 @@ const PostulationsEstudent = () => {
}, [])
const eliminarPostulacion = async (id) => {
- const respuesta = await deletePostulation.handleRequest("DELETE", "/postulations/?id_postulacion=" + id)
+ const respuesta = await deletePostulation.handleRequest(
+ "DELETE",
+ `/postulations/?id_postulacion=${id}`
+ )
if (respuesta.status === 200) {
setTypePopUp(3)
setError("Postulación eliminada con éxito")
setWarning(true)
obtainPostulations()
- } else {
+ } else {
setTypePopUp(1)
setError("No se pudo eliminar la postulación")
setWarning(true)
@@ -43,11 +54,11 @@ const PostulationsEstudent = () => {
message={error}
status={warning}
style={typePopUp}
- close = {() => setWarning(false)}
+ close={() => setWarning(false)}
/>
- {api.data ? (
+ {postulaciones.postulations && postulaciones.postulations.length > 0 ? (
- {api.data.postulations.map((postulation) => (
+ {postulaciones.postulations.map((postulation) => (
{
+ const enterprisesApi = useApi()
+ const [enterprises, setEnterprises] = useState([])
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [loading, setLoading] = useState(true)
+
+ const obtainEnterprises = async () => {
+ const data = await enterprisesApi.handleRequest("GET", "/admins/companies")
+ if (data.status === 200) {
+ setEnterprises(data.data)
+ } else {
+ setTypeError(1)
+ setError("Ups, algo salio mal al obtener las empresas")
+ setWarning(true)
+ }
+ setLoading(false)
+ }
+
+ const [searchTerm, setSearchTerm] = useState("")
+
+ const [showSearch, setShowSearch] = useState(false)
+
+ const handleSearchChange = (event) => {
+ setSearchTerm(event.target.value)
+ }
+
+ const filteredEnterprises = enterprises.companies
+ ? enterprises.companies.filter((enterprise) =>
+ enterprise.nombre.toLowerCase().includes(searchTerm.toLowerCase())
+ )
+ : []
+
+ const handleClick = (e) => {
+ navigate(`/publicProfileAdminEnterprise/${e}`)
+ }
+
+ useEffect(() => {
+ obtainEnterprises()
+ }, [])
+
+ return (
+
+
+
setWarning(false)}
+ />
+
+ setShowSearch(!showSearch)}
+ />
+ {showSearch && (
+
+ )}
+
+ {loading ? (
+
+ ) : (
+
+ {filteredEnterprises.length > 0 ? (
+ filteredEnterprises.map((enterprise) => {
+ const pfpUrlEmisor =
+ enterprise.foto === ""
+ ? "/images/pfp.svg"
+ : `${API_URL}/api/uploads/${enterprise.foto}`
+ return (
+ {
+ handleClick(enterprise.id_empresa)
+ }}
+ showState
+ state={enterprise.suspendido}
+ />
+ )
+ })
+ ) : (
+ No hay empresas
+ )}
+
+ )}
+
+ )
+}
+
+export default PrincipalAdmin
diff --git a/uniEmpleos/src/pages/PricipalAdmin/PrincipalAdmin.module.css b/uniEmpleos/src/pages/PricipalAdmin/PrincipalAdmin.module.css
new file mode 100644
index 00000000..68841fb4
--- /dev/null
+++ b/uniEmpleos/src/pages/PricipalAdmin/PrincipalAdmin.module.css
@@ -0,0 +1,37 @@
+.enterprisesContainer {
+ width: 100%;
+ display: flex;
+ flex-wrap: wrap;
+ padding-top: 20px;
+}
+
+.searchBar{
+ padding: 10px;
+ width: 100%;
+ border: 2px solid #94bd0f;
+ color: #000;
+ font-size: 20px;
+ border-radius: 50px;
+ background-color: #fff;
+ font-size: 14px;
+}
+
+input.searchBar::placeholder{
+ color: #000;
+}
+
+.searchBar:focus{
+ outline: none;
+}
+
+.searchContainer{
+ display: flex;
+ align-items: center;
+ padding: 20px;
+ gap: 20px;
+}
+
+.searchContainer svg{
+ cursor: pointer;
+}
+
diff --git a/uniEmpleos/src/pages/PrincipalStudent/PrincipalStudent.jsx b/uniEmpleos/src/pages/PrincipalStudent/PrincipalStudent.jsx
index 46c3749a..f6b892eb 100644
--- a/uniEmpleos/src/pages/PrincipalStudent/PrincipalStudent.jsx
+++ b/uniEmpleos/src/pages/PrincipalStudent/PrincipalStudent.jsx
@@ -7,6 +7,7 @@ import { Header } from "../../components/Header/Header"
import useConfig from "../../Hooks/Useconfig"
import API_URL from "../../api"
import useApi from "../../Hooks/useApi"
+import Loader from "../../components/Loader/Loader"
const schema = Joi.object({
token: Joi.string().required(),
@@ -21,6 +22,7 @@ const PrincipalStudent = () => {
const [carrera, setCarrera] = useState("")
const [postulaciones, setPostulaciones] = useState([])
const [ofertasAMostrar, setOfertasAMostrar] = useState([])
+ const [loading, setLoading] = useState(false)
const form = useConfig(schema, {
token: "a",
@@ -31,6 +33,7 @@ const PrincipalStudent = () => {
const [dataa, setData] = useState([])
const configureData = async () => {
+ setLoading(true)
const response = await fetch(`${API_URL}/api/postulations/previews`, {
method: "GET",
headers: {
@@ -92,18 +95,21 @@ const PrincipalStudent = () => {
}
})
setOfertasAMostrar(ofertas)
+ setLoading(false)
}
useEffect(() => {
if (dataa.status === 200) {
handleOfertasAMostrar()
}
- }, [dataa.data, carrera])
+ }, [dataa.data, carrera, postulaciones])
return (
- {dataa.status === 200 && ofertasAMostrar.length > 0 ? (
+ {loading ? (
+
+ ) : dataa.status === 200 && ofertasAMostrar.length > 0 ? (
{ofertasAMostrar.map((postulation) => (
{
+ const correo = params.split("-")[0]
+ const idOferta = params.split("-")[1]
+ const api = useApi()
+ const carreraApi = useApi()
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [usuario, setUsuario] = useState([])
+ const [carrera, setCarrera] = useState("")
+ const [edad, setEdad] = useState("")
+
+ const obtenerCarrera = async () => {
+ const datos = await carreraApi.handleRequest("GET", "/careers")
+ if (datos.status === 200 && usuario.carrera) {
+ for (let i = 0; i < datos.data.careers.length; i += 1) {
+ if (datos.data.careers[i].id_carrera === usuario.carrera) {
+ setCarrera(datos.data.careers[i].nombre)
+ }
+ }
+ }
+ }
+
+ const calcularEdad = () => {
+ const fechaNacimientoObj = new Date(usuario.nacimiento)
+ const fechaActual = new Date()
+ const diferencia = fechaActual - fechaNacimientoObj
+ const edadActual = Math.floor(diferencia / (365.25 * 24 * 60 * 60 * 1000))
+ setEdad(edadActual)
+ }
+
+ const obtenerPostulante = async () => {
+ const datos = await api.handleRequest("POST", "/users/details", {
+ correo,
+ })
+ if (datos.status === 200) {
+ if (datos.data.student) {
+ setUsuario(datos.data.student)
+ } else {
+ setUsuario(datos.data.company)
+ }
+ } else {
+ setTypeError(1)
+ setError("Ups, algo salio mal al obtener el perfil")
+ setWarning(true)
+ setTimeout(() => {
+ navigate(`/postulantes/${idOferta}`)
+ }, 5000)
+ }
+ }
+
+ useEffect(() => {
+ obtenerPostulante()
+ }, [])
+
+ useEffect(() => {
+ if (usuario) {
+ obtenerCarrera()
+ calcularEdad()
+ }
+ }, [usuario])
+
+ return (
+
+
setWarning(false)}
+ />
+ navigate(`/postulantes/${idOferta}`)}
+ />
+ {usuario ? (
+
+
+ Perfil de {usuario.nombre} {usuario.apellido}
+
+
+ {usuario.foto && (
+
+
+
+ )}
+
+
+
+
+ Nombre: {`${usuario.nombre} ${usuario.apellido}`}
+
+
+
+
+ Correo: {usuario.correo}
+
+
+
+
+ Telefono: {usuario.telefono}
+
+
+ {usuario.universidad && (
+
+
+
+ Universidad: {usuario.universidad}
+
+
+ )}
+ {usuario.carrera && (
+
+ )}
+ {usuario.nacimiento && (
+
+
+ Edad: {edad}
+
+ )}
+ {usuario.semestre && (
+
+
+
+ Semestre: {usuario.semestre}
+
+
+ )}
+
+
+
+ ) : (
+ Cargando
+ )}
+
+ )
+}
+
+export default PublicProfile
diff --git a/uniEmpleos/src/pages/PublicProfile/PublicProfile.module.css b/uniEmpleos/src/pages/PublicProfile/PublicProfile.module.css
new file mode 100644
index 00000000..d347f52a
--- /dev/null
+++ b/uniEmpleos/src/pages/PublicProfile/PublicProfile.module.css
@@ -0,0 +1,123 @@
+.infoContainer {
+ width: calc(100% - 50px);
+ color: #000;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 20px;
+ padding: 25px;
+}
+.title{
+ font-size: 30px;
+ font-weight: 700;
+ color: #333333;
+ text-align: center;
+ margin-bottom: 20px;
+ text-transform: capitalize;
+}
+
+.pfpContainer {
+ display: flex;
+ justify-content: end;
+ align-items: end;
+ width: 50%;
+ height: 50%;
+}
+
+.tipoContainer{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ gap:10%;
+}
+
+.pfp {
+ display: flex;
+ width: 60%;
+ height: 60%;
+ border-radius: 10%;
+ box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
+
+}
+
+.profileSpan{
+ font-size: 20px;
+ color: #333333;
+ text-align: center;
+ text-transform: capitalize;
+}
+
+.correo{
+ font-size: 20px;
+ color: #333333;
+ text-align: center;
+}
+
+.subInfoContainer {
+ width: calc(100%/2);
+ gap: 20px;
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: column;
+ align-items: start;
+}
+
+.profileli{
+ justify-content: center;
+ align-items: center;
+ display: flex;
+}
+
+.subInfoContainer > * {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap:10px;
+}
+
+
+@media screen and (max-width: 768px){
+ .pfpContainer {
+ width: 100%;
+ height: 100%;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .pfp {
+ width: 100%;
+ height: 100%;
+ }
+
+ .profileSpan{
+ font-size: 16px;
+ color: #333333;
+ text-align: center;
+ text-transform: capitalize;
+ }
+
+ .correo{
+ font-size: 16px;
+ color: #333333;
+ text-align: center;
+ }
+
+
+ .tipoContainer{
+ flex-direction: column;
+ gap: 10%;
+ }
+
+ .subInfoContainer {
+ width: 100%;
+ gap: 0;
+ align-items: start;
+ margin-top: 10%;
+ }
+
+ .subInfoContainer > * {
+ gap: 10px;
+ }
+}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.jsx b/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.jsx
new file mode 100644
index 00000000..ba2c3a18
--- /dev/null
+++ b/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.jsx
@@ -0,0 +1,186 @@
+import React, { useEffect, useState } from "react"
+import { BiArrowBack } from "react-icons/bi"
+import style from "./PublicProfileAdminEnterprise.module.css"
+import useApi from "../../Hooks/useApi"
+import InfoTab from "../../components/InfoTab/InfoTab"
+import Popup from "../../components/Popup/Popup"
+import { navigate } from "../../store"
+import Loader from "../../components/Loader/Loader"
+import PublicProfileAdmin from "../../components/PublicProfile/PublicProfileAdmin"
+import API_URL from "../../api"
+
+const PublicProfileAdminEnterprise = ({ id }) => {
+ const enterpriseInfoApi = useApi()
+ const offersApi = useApi()
+ const api = useApi()
+
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [enterpriseInfo, setEnterpriseInfo] = useState([])
+ const [loadingInfoEnterprise, setLoadingInfoEnterprise] = useState(true)
+ const [loadingOffers, setLoadingOffers] = useState(true)
+ const [offers, setOffers] = useState([])
+
+ const obtainEnterpriseInfo = async () => {
+ const data = await enterpriseInfoApi.handleRequest(
+ "POST",
+ "/admins/details",
+ {
+ correo: id,
+ }
+ )
+ if (data.status === 200) {
+ if (data.data.company) {
+ setEnterpriseInfo(data.data.company)
+ } else {
+ setTypeError(1)
+ setError("Error al obtener la informacion de la empresa")
+ setWarning(true)
+ }
+ } else {
+ setTypeError(1)
+ setError("Error al obtener la informacion de la empresa")
+ setWarning(true)
+ }
+ setLoadingInfoEnterprise(false)
+ }
+
+ const obtainOffers = async () => {
+ const data = await offersApi.handleRequest("POST", "/offers/company", {
+ id_empresa: id,
+ })
+ if (data.status === 200) {
+ setOffers(data.data.offers)
+ } else {
+ setTypeError(1)
+ setError("Error al obtener las ofertas de la empresa")
+ setWarning(true)
+ }
+ setLoadingOffers(false)
+ }
+
+ const suspendedUser = async () => {
+ const data = await api.handleRequest("POST", "/admins/suspend", {
+ id_usuario: id,
+ suspender: !enterpriseInfo.suspendido,
+ })
+ if (data.status === 200) {
+ if (data.message === "Account Reactivated Successfully") {
+ setTypeError(3)
+ setError("Cuenta reactivada exitosamente")
+ setWarning(true)
+ } else {
+ setTypeError(3)
+ setError("Cuenta suspendida exitosamente")
+ setWarning(true)
+ }
+ } else {
+ setTypeError(1)
+ setError("Error al suspender la cuenta")
+ setWarning(true)
+ }
+ }
+
+ const deleteUser = async () => {
+ const data = await api.handleRequest(
+ "POST",
+ `/admins/delete/user?usuario=${id}`
+ )
+ if (data.status === 200) {
+ setTypeError(3)
+ setError("Cuenta eliminada exitosamente")
+ setWarning(true)
+ setTimeout(() => {
+ navigate("/profileadmin")
+ }, 5000)
+ } else {
+ setTypeError(1)
+ setError("Error al eliminar la cuenta")
+ setWarning(true)
+ }
+ }
+
+ const handleShowMore = (e) => {
+ navigate(`/adminSPD/${e}`)
+ }
+
+ const handleSuspended = () => {
+ setTimeout(() => {
+ obtainEnterpriseInfo()
+ }, 5000)
+ suspendedUser()
+ }
+
+ const handleDelete = () => {
+ deleteUser()
+ }
+
+ useEffect(() => {
+ obtainEnterpriseInfo()
+ obtainOffers()
+ }, [])
+
+ return (
+
+
setWarning(false)}
+ />
+ navigate("/profileadmin")}
+ />
+
+ {loadingInfoEnterprise && enterpriseInfo && loadingOffers ? (
+
+ ) : (
+
+
+
Ofertas de la empresa
+
+ {offers ? (
+ offers.map((offer) => (
+ {
+ handleShowMore(offer.id_oferta)
+ }}
+ />
+ ))
+ ) : (
+ No hay ofertas
+ )}
+
+
+ )}
+
+
+ )
+}
+
+export default PublicProfileAdminEnterprise
diff --git a/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.module.css b/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.module.css
new file mode 100644
index 00000000..a1bf7ddd
--- /dev/null
+++ b/uniEmpleos/src/pages/PublicProfileAdminEnterprise/PublicProfileAdminEnterprise.module.css
@@ -0,0 +1,51 @@
+.mainContainer {
+ width: 100%;
+ height: 100%;
+}
+
+.infoProfileContainer {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.postulationContainer {
+ width: 100%;
+ height: 60%;
+}
+
+.offersContainer {
+ padding: 0 20px;
+ height: 50%;
+ width: calc(100% - 40px);
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 20px;
+}
+
+.infoEnterpriseContainer {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
+ justify-content: center;
+ padding-top: 10%;
+}
+
+.title {
+ color: #333;
+ text-align: center;
+ margin: 0 0 60px 0;
+}
+
+@media screen and (max-width: 768px) {
+ .title{
+ margin: 10%;
+ }
+}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.jsx b/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.jsx
new file mode 100644
index 00000000..e02aa3a8
--- /dev/null
+++ b/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.jsx
@@ -0,0 +1,188 @@
+import React, { useState, useEffect } from "react"
+import { BiArrowBack } from "react-icons/bi"
+import style from "./PublicProfileAdminStudent.module.css"
+import PublicProfileAdmin from "../../components/PublicProfile/PublicProfileAdmin"
+import InfoTab from "../../components/InfoTab/InfoTab"
+import useApi from "../../Hooks/useApi"
+import Popup from "../../components/Popup/Popup"
+import { navigate } from "../../store"
+import Loader from "../../components/Loader/Loader"
+import API_URL from "../../api"
+
+const PublicProfileAdminStudent = ({ id }) => {
+ const studentInfoApi = useApi()
+ const postulationsApi = useApi()
+ const api = useApi()
+
+ const [warning, setWarning] = useState(false)
+ const [error, setError] = useState("")
+ const [typeError, setTypeError] = useState(1)
+ const [postulations, setPostulations] = useState([])
+ const [studentInfo, setStudentInfo] = useState([])
+ const [loadingInfoStudent, setLoadingInfoStudent] = useState(true)
+ const [loadingPostulations, setLoadingPostulations] = useState(true)
+
+ const obtainStudentInfo = async () => {
+ const data = await studentInfoApi.handleRequest("POST", "/admins/details", {
+ correo: id,
+ })
+
+ if (data.status === 200) {
+ if (data.data.student) {
+ setStudentInfo(data.data.student)
+ } else {
+ setTypeError(1)
+ setError("Error al obtener la informacion del estudiante")
+ setWarning(true)
+ }
+ } else {
+ setTypeError(1)
+ setError("Error al obtener la informacion del estudiante")
+ setWarning(true)
+ }
+ setLoadingInfoStudent(false)
+ }
+
+ const obtainPostulationsStudent = async () => {
+ const data = await postulationsApi.handleRequest(
+ "POST",
+ `/admins/postulations?id_estudiante=${id}`
+ )
+ if (data.status === 200) {
+ setPostulations(data.data.postulations)
+ } else {
+ setTypeError(1)
+ setError("Error al obtener las postulaciones")
+ setWarning(true)
+ }
+ setLoadingPostulations(false)
+ }
+
+ const suspendedStudent = async () => {
+ const data = await api.handleRequest("POST", "/admins/suspend", {
+ id_usuario: id,
+ suspender: !studentInfo.suspendido,
+ })
+ if (data.status === 200) {
+ if (data.message === "Account Reactivated Successfully") {
+ setTypeError(3)
+ setError("Cuenta reactivada exitosamente")
+ setWarning(true)
+ } else {
+ setTypeError(3)
+ setError("Cuenta suspendida exitosamente")
+ setWarning(true)
+ }
+ } else {
+ setTypeError(1)
+ setError("Error al suspender la cuenta")
+ setWarning(true)
+ }
+ }
+
+ const deleteStudent = async () => {
+ const data = await api.handleRequest(
+ "POST",
+ `/admins/delete/user?usuario=${id}`
+ )
+ if (data.status === 200) {
+ setTypeError(3)
+ setError("Cuenta eliminada exitosamente")
+ setWarning(true)
+ setTimeout(() => {
+ navigate("/profileadminstudent")
+ }, 5000)
+ } else {
+ setTypeError(1)
+ setError("Error al eliminar la cuenta")
+ setWarning(true)
+ }
+ }
+
+ const handleSuspended = () => {
+ setTimeout(() => {
+ obtainStudentInfo()
+ }, 5000)
+ suspendedStudent()
+ }
+
+ const handleDelete = () => {
+ deleteStudent()
+ }
+
+ const handleShowMore = (id_oferta, id_postulacion) => {
+ navigate(`/adminSPDS/${id_oferta}-${id_postulacion}-${id}`)
+ }
+
+ useEffect(() => {
+ obtainStudentInfo()
+ obtainPostulationsStudent()
+ }, [])
+
+ return (
+
+
setWarning(false)}
+ />
+ navigate("/profileadminstudent")}
+ />
+
+ {loadingInfoStudent && studentInfo && loadingPostulations ? (
+
+ ) : (
+
+
+
Postulaciones del estudiante
+
+ {postulations.length ? (
+ postulations.map((postulation) => (
+ {
+ handleShowMore(
+ postulation.id_oferta,
+ postulation.id_postulacion
+ )
+ }}
+ />
+ ))
+ ) : (
+ No hay postulaciones
+ )}
+
+
+ )}
+
+
+ )
+}
+
+export default PublicProfileAdminStudent
diff --git a/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.module.css b/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.module.css
new file mode 100644
index 00000000..90395cf9
--- /dev/null
+++ b/uniEmpleos/src/pages/PublicProfileAdminStudent/PublicProfileAdminStudent.module.css
@@ -0,0 +1,46 @@
+.mainContainer {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+}
+
+.infoProfileContainer {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.postulationContainer {
+ width: 100%;
+ height: 60%;
+}
+
+.postulationsContainer {
+ padding: 0 20px;
+ height: 50%;
+ width: calc(100% - 40px);
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 20px;
+}
+
+.title {
+ color: #333;
+ text-align: center;
+ margin: 0 0 60px 0;
+}
+
+.infoStudentContainer{
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
+ justify-content: center;
+ padding-top: 10%;
+}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/SignUpEmpresa/SignUpEmpresa.jsx b/uniEmpleos/src/pages/SignUpEmpresa/SignUpEmpresa.jsx
index d62b7504..d0544393 100644
--- a/uniEmpleos/src/pages/SignUpEmpresa/SignUpEmpresa.jsx
+++ b/uniEmpleos/src/pages/SignUpEmpresa/SignUpEmpresa.jsx
@@ -4,14 +4,10 @@ import ComponentInput from "../../components/Input/Input"
import TextArea from "../../components/textAreaAutosize/TextAreaAuto"
import Button from "../../components/Button/Button"
import { navigate } from "../../store"
-import API_URL from "../../api"
-import ImageUploader from "../../components/ImageUploader/ImageUploader"
import Popup from "../../components/Popup/Popup"
-import useIsImage from "../../Hooks/useIsImage"
import useApi from "../../Hooks/useApi"
const SignUpEmpresa = () => {
- const isImage = useIsImage()
const api = useApi()
const [nombre, setNombre] = useState("")
@@ -19,7 +15,6 @@ const SignUpEmpresa = () => {
const [detalles, setDetalles] = useState("")
const [telefono, setTelefono] = useState("")
const [password, setPassword] = useState("")
- const [uploadedImage, setUploadedImage] = useState("")
const [warning, setWarning] = useState(false)
const [error, setError] = useState("")
const [showPassword, setShowPassword] = useState(false)
@@ -71,7 +66,7 @@ const SignUpEmpresa = () => {
correo,
telefono,
contra: password,
- foto: uploadedImage,
+ foto: "",
})
if (apiResponse.status === 200) {
setTypeError(3)
@@ -92,17 +87,6 @@ const SignUpEmpresa = () => {
}
}
- const handleUploadFile = (uploadedImage) => {
- const fileType = isImage(uploadedImage)
- if (fileType) {
- setUploadedImage(uploadedImage)
- } else {
- setTypeError(2)
- setError("El archivo debe ser una imagen")
- setWarning(true)
- }
- }
-
const handlePassword = () => {
setShowPassword(!showPassword)
}
@@ -155,23 +139,11 @@ const SignUpEmpresa = () => {
type="password"
placeholder="micontraseña123"
onChange={handleInputsValue}
- eye={true}
+ eye
onClickButton={handlePassword}
isOpen={showPassword}
/>
-
diff --git a/uniEmpleos/src/pages/SignUpEstudiante/SignUpEstudiante.module.css b/uniEmpleos/src/pages/SignUpEstudiante/SignUpEstudiante.module.css
index 1e5f1a35..c2096e22 100644
--- a/uniEmpleos/src/pages/SignUpEstudiante/SignUpEstudiante.module.css
+++ b/uniEmpleos/src/pages/SignUpEstudiante/SignUpEstudiante.module.css
@@ -124,4 +124,41 @@
justify-content: center;
align-items: center;
padding: 0 10px 0 10px;
+}
+
+@media (max-width: 600px){
+
+ .inputsContainer{
+ width: 80%;
+
+ }
+
+ .grupoDatos1{
+ flex-direction: column;
+ gap: 10px;
+ width: 100%;
+ flex-wrap: nowrap;
+ }
+
+ .inputTextArea {
+ width: 80%;
+ }
+
+ .inputSubContainer{
+ width: 100%;
+ }
+
+ .inputTextArea {
+ width: 100%;
+ }
+
+ .buttonContainer{
+ width: 100%;
+ padding: 0;
+ }
+
+ .inputSubContainerDataGroup1 {
+ width: 100%;
+ }
+
}
\ No newline at end of file
diff --git a/uniEmpleos/src/pages/index.jsx b/uniEmpleos/src/pages/index.jsx
index fd0c2906..82a6fdd1 100644
--- a/uniEmpleos/src/pages/index.jsx
+++ b/uniEmpleos/src/pages/index.jsx
@@ -16,6 +16,14 @@ import NewOffer from "./nuevaOferta/NewOffer"
import ChatPage from "./ChatPage/ChatPage"
import PostulationsEstudent from "./PostulationsEstudentPage/PostulationsEstudent"
import OfferDetails from "./OfferDetails/OfferDetails"
+import PostulantesPage from "./PostulantesPage/PostulantesPage"
+import PublicProfile from "./PublicProfile/PublicProfile"
+import PrincipalAdmin from "./PricipalAdmin/PrincipalAdmin"
+import AdminShowPostulationDetails from "./AdminShowPostulationDetails/AdminShowPostulationDetails"
+import ProfileAdminStudent from "./AdminStudent/AdminStudent"
+import PublicProfileAdminStudent from "./PublicProfileAdminStudent/PublicProfileAdminStudent"
+import PublicProfileAdminEnterprise from "./PublicProfileAdminEnterprise/PublicProfileAdminEnterprise"
+import AdminShowPostulationDetailsStudent from "./AdminShowPostulationDetailsStudent/AdminShowPostulationDetailsStudent"
const Page = () => {
const { [routerKey]: route } = useStoreon(routerKey)
@@ -34,6 +42,9 @@ const Page = () => {
case "principalStudent":
Component =
break
+ case "principaladmin":
+ Component =
+ break
case "signupestudiante":
Component =
break
@@ -67,6 +78,27 @@ const Page = () => {
case "postulaciones":
Component =
break
+ case "postulantes":
+ Component =
+ break
+ case "publicprofile":
+ Component =
+ break
+ case "adminShowPostulationDetails":
+ Component =
+ break
+ case "adminStudent":
+ Component =
+ break
+ case "publicprofileadminstudent":
+ Component =
+ break
+ case "publicprofileadminenterprise":
+ Component =
+ break
+ case "adminShowPostulationDetailsStudent":
+ Component =
+ break
default:
Component =
404 Error
}
diff --git a/uniEmpleos/src/pages/nuevaOferta/NewOffer.jsx b/uniEmpleos/src/pages/nuevaOferta/NewOffer.jsx
index f8939575..4bf9d69d 100644
--- a/uniEmpleos/src/pages/nuevaOferta/NewOffer.jsx
+++ b/uniEmpleos/src/pages/nuevaOferta/NewOffer.jsx
@@ -1,5 +1,7 @@
import React, { useEffect, useState } from "react"
+import Select from "react-select"
import { useStoreon } from "storeon/react"
+import { useQuill } from "react-quilljs"
import style from "./NewOffer.module.css"
import { Header } from "../../components/Header/Header"
import Button from "../../components/Button/Button"
@@ -8,7 +10,6 @@ import TextArea from "../../components/textAreaAutosize/TextAreaAuto"
import DropDown from "../../components/dropDown/DropDown"
import { navigate } from "../../store"
import useApi from "../../Hooks/useApi"
-import { useQuill } from "react-quilljs"
import "react-quill/dist/quill.snow.css"
import Popup from "../../components/Popup/Popup"
@@ -58,7 +59,7 @@ const Postulacion = () => {
}
const handleCarrera = (e) => {
- setCarrera(e.target.value)
+ setCarrera(e.value)
}
const handleInputsValue = (e) => {
@@ -132,12 +133,34 @@ const Postulacion = () => {
Carrera
- ({
+ ...baseStyles,
+ borderColor: state.isFocused ? "#a08ae5" : "grey",
+ color: "black",
+ }),
+ option: (baseStyles) => ({
+ ...baseStyles,
+ color: "black",
+ }),
+ }}
+ name="carrera"
+ theme={(theme) => ({
+ ...theme,
+ colors: {
+ ...theme.colors,
+ primary25: "#94bd0f",
+ primary: "#a08ae5",
+ },
+ })}
+ defaultValue={carrera}
+ options={carreras}
+ value={carreras.find((option) => option.label === carrera)}
onChange={handleCarrera}
/>
+
Requisitos