Skip to content

Commit 859c091

Browse files
authored
Merge pull request #56 from FSDSTR0225/dev
Dev
2 parents 7317449 + e66887b commit 859c091

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1890
-1389
lines changed

src/components/AvatarImage.jsx

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,85 @@
1+
import { capitalize, getInitials } from "../utils/utils";
2+
import { useContext } from "react";
3+
import { AuthContext } from "../context/authContext";
4+
import { useState } from "react";
15

2-
import { capitalize, getInitials } from '../utils/utils';
3-
import { useContext } from 'react';
4-
import { AuthContext } from '../context/authContext';
5-
import { useState } from 'react';
6-
7-
export const AvatarImage = ({user, width}) => {
8-
const {onlineUsers} = useContext(AuthContext);
9-
const isDeveloper = user?.role?.type === "developer";
10-
const userOnline = onlineUsers.includes(user?._id);
6+
export const AvatarImage = ({ user, width }) => {
7+
const { onlineUsers } = useContext(AuthContext);
8+
const isDeveloper = user?.role?.type === "developer";
9+
const userOnline = onlineUsers.includes(user?._id);
1110

1211
// Para usar este componente son necesario 2 Props.
1312
// user donde le pasaremos la imagen del avatar si es del owner, recruiter. profile
1413
// width donde pondremos un numero de width
15-
{/* <AvatarImage user={offer.owner} width={8} />
16-
<AvatarImage user={profile} /> */}
14+
{
15+
/* <AvatarImage user={offer.owner} width={8} />
16+
<AvatarImage user={profile} /> */
17+
}
1718

18-
const sizeClasses = {
19-
4: 'size-4',
20-
5: 'size-5',
21-
6: 'size-6',
22-
7: 'size-7',
23-
8: 'size-8',
24-
9: 'size-9',
25-
10: 'size-10',
26-
11: 'size-11',
27-
12: 'size-12',
28-
14: 'size-14',
29-
16: 'size-16',
30-
20: 'size-20',
31-
24: 'size-24',
32-
32: 'size-32',
19+
const sizeClasses = {
20+
4: "size-4",
21+
5: "size-5",
22+
6: "size-6",
23+
7: "size-7",
24+
8: "size-8",
25+
9: "size-9",
26+
10: "size-10",
27+
11: "size-11",
28+
12: "size-12",
29+
14: "size-14",
30+
16: "size-16",
31+
20: "size-20",
32+
24: "size-24",
33+
32: "size-32",
3334
};
3435

35-
3636
const sizeClass = sizeClasses[width] || sizeClasses[10];
3737

38-
const name = capitalize(user?.name || '');
39-
const surname = capitalize(user?.surname || '');
40-
const completeName = `${name} ${surname}`.trim() || 'Unknown Recruiter';
41-
42-
const [imgError, setImgError] = useState(null);
38+
const name = capitalize(user?.name || "");
39+
const surname = capitalize(user?.surname || "");
40+
const completeName = `${name} ${surname}`.trim() || "Unknown Recruiter";
4341

42+
const [imgError, setImgError] = useState(null);
4443

4544
return (
46-
< >
47-
{( user?.avatar && !imgError) ? (
48-
<div className={`avatar outline-2 outline-neutral-60 rounded-full ${userOnline && (isDeveloper ? 'avatar-online before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] before:bg-primary-50 outline-primary-50 ' : 'before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] outline-secondary-50 avatar-online before:bg-secondary-50')}`}>
49-
<div className={`rounded-full ${sizeClass} `}>
50-
<img
51-
src={ user?.avatar}
52-
alt='Avatar'
53-
onError={() => setImgError(true)}
54-
/>
55-
</div>
56-
</div>
57-
) : (
58-
<div className={`avatar avatar-placeholder outline-2 outline-neutral-60 rounded-full ${userOnline && (isDeveloper ? 'avatar-online before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] before:bg-primary-50 outline-primary-50 ' : 'before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] outline-secondary-50 avatar-online before:bg-secondary-50')}`}>
59-
<div className={`bg-neutral text-neutral-content rounded-full ${sizeClass}`}>
60-
<span className=' font-bold'>{getInitials(completeName)}</span>
61-
</div>
62-
</div>
63-
)}
64-
{/* <div className="flex flex-col -space-y-1">
45+
<>
46+
{user?.avatar && !imgError ? (
47+
<div
48+
className={`avatar outline-2 outline-neutral-60 rounded-full ${
49+
userOnline &&
50+
(isDeveloper
51+
? "avatar-online before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] before:bg-primary-50 outline-primary-50 "
52+
: "before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] outline-secondary-50 avatar-online before:bg-secondary-50")
53+
}`}
54+
>
55+
<div className={`rounded-full ${sizeClass} `}>
56+
<img
57+
src={user?.avatar}
58+
alt="Avatar"
59+
onError={() => setImgError(true)}
60+
/>
61+
</div>
62+
</div>
63+
) : (
64+
<div
65+
className={`avatar avatar-placeholder outline-2 outline-neutral-60 rounded-full ${
66+
userOnline &&
67+
(isDeveloper
68+
? "avatar-online before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] before:bg-primary-50 outline-primary-50 "
69+
: "before:w-[20%] before:h-[20%] before:top-[6%] before:right-[2%] outline-secondary-50 avatar-online before:bg-secondary-50")
70+
}`}
71+
>
72+
<div
73+
className={`bg-neutral text-neutral-content rounded-full ${sizeClass}`}
74+
>
75+
<span className=" font-bold">{getInitials(completeName)}</span>
76+
</div>
77+
</div>
78+
)}
79+
{/* <div className="flex flex-col -space-y-1">
6580
<p className='text-sm'>{completeName}</p>
6681
<p className="text-xs text-neutral-10 ">{profile?.role?.type || owner?.role?.type}</p>
6782
</div> */}
68-
</>
69-
)
70-
}
83+
</>
84+
);
85+
};

src/components/NameUsers.jsx

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,43 @@ import { capitalize } from "../utils/utils";
44
// user donde le pasaremos si el nombre es del owner, recruiter. profile
55
// children si queresmos rol
66
// Y classProps Para modificar solo el componente principal
7-
{/* <NameUsers user={profile} classProps={"text-xs"}>
7+
{
8+
/* <NameUsers user={profile} classProps={"text-xs"}>
89
{profile.role.type === "recruiter" ? "Recruiter" : "Developer"}
9-
</NameUsers> */}
10+
</NameUsers> */
11+
}
1012
// o
1113
// <NameUsers user={offer.owner} classProps={"text-xs"}/>
1214

15+
export const NameUsers = ({
16+
user,
17+
classProps,
18+
children,
19+
align = "items-center",
20+
}) => {
21+
const name = capitalize(user?.name || "");
22+
const surname = capitalize(user?.surname || "");
23+
const completeName = `${name} ${surname}`.trim() || "Unknown Recruiter";
1324

14-
export const NameUsers = ({user, classProps, children, align="items-center" }) => {
15-
16-
const name = capitalize(user?.name || '');
17-
const surname = capitalize(user?.surname || '');
18-
const completeName = `${name} ${surname}`.trim() || 'Unknown Recruiter';
19-
20-
let display = ''
21-
if(typeof children === "string")
22-
{ display = capitalize(children)
23-
}else{
24-
display = children
25+
let display = "";
26+
if (typeof children === "string") {
27+
display = capitalize(children);
28+
} else {
29+
display = children;
2530
}
26-
;
27-
2831
return (
29-
<div className={`flex flex-col ${align}`}>
30-
<span className={`font-bold ${classProps}`}>{completeName}</span>
31-
<span className={`text-xs text-neutral-10` }>{display}</span>
32+
<div
33+
className={`flex flex-col ${align}`}
34+
style={{ minWidth: 0, maxWidth: "100%" }}
35+
>
36+
<span
37+
className={`font-bold ${classProps} truncate whitespace-nowrap block`}
38+
style={{ maxWidth: "100%" }}
39+
>
40+
{completeName}
41+
</span>
42+
43+
<span className={`text-xs text-neutral-10`}>{display}</span>
3244
</div>
33-
)
34-
}
45+
);
46+
};

src/components/SectionContainer.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22

33
export const SectionContainer = ({children, classProps}) => {
44
return (
5-
<section className={`flex flex-col justify-center max-w-screen-xl mx-auto p-4 ${classProps || ""}`}>
5+
<section className={`flex flex-col justify-center max-w-screen-xl mx-auto p-4 py-10 ${classProps || ""}`}>
66
{children}
77
</section>
88
)

src/components/TalentsCard.jsx

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React from "react";
1+
import React, { useRef, useState, useEffect } from "react";
22
import { Link } from "react-router";
3+
import { NameUsers } from "../components/NameUsers";
4+
import { useContainerWidth } from "../hooks/useContainerWidth"; // Ajusta ruta según corresponda
35

46
export const TalentsCard = ({
5-
name,
6-
surname,
7+
developer,
78
avatar,
89
profession,
910
experienceYears,
@@ -12,6 +13,36 @@ export const TalentsCard = ({
1213
developerId,
1314
projectImage,
1415
}) => {
16+
const skillsContainerRef = useRef(null);
17+
const containerWidth = useContainerWidth(skillsContainerRef);
18+
const [visibleSkills, setVisibleSkills] = useState([]);
19+
20+
useEffect(() => {
21+
if (!containerWidth || skills.length === 0) return;
22+
23+
const estimateSkillWidth = (skill) => {
24+
const baseWidth = 24; // padding + margen aproximado para text-xs y px-2 py-0.5
25+
const charWidth = 6; // ancho aproximado por carácter para text-xs
26+
return baseWidth + charWidth * skill.length;
27+
};
28+
29+
let usedWidth = 0;
30+
const selected = [];
31+
32+
for (let i = 0; i < skills.length; i++) {
33+
const w = estimateSkillWidth(skills[i]);
34+
if (usedWidth + w <= containerWidth - 40) {
35+
// 40px margen para el +N
36+
usedWidth += w + 4; // 4px espacio entre skills
37+
selected.push(skills[i]);
38+
} else {
39+
break;
40+
}
41+
}
42+
43+
setVisibleSkills(selected);
44+
}, [containerWidth, skills]);
45+
1546
return (
1647
<Link
1748
to={`/profile/${developerId}`}
@@ -36,21 +67,33 @@ export const TalentsCard = ({
3667

3768
{/* Avatar flotante */}
3869
<div className="absolute top-11 left-1/2 transform -translate-x-1/2 z-20">
70+
{/* Capa con borde degradado */}
3971
<div className="p-0.5 rounded-full bg-gradient-to-br from-primary-40 to-secondary-40">
40-
<figure>
72+
{/* Máscara circular con fondo blanco */}
73+
<div className="rounded-full bg-white w-24 h-24 overflow-hidden flex items-center justify-center">
74+
{/* Imagen centrada, ajustando proporciones sin deformar */}
4175
<img
4276
src={avatar}
4377
alt="Avatar"
44-
className="w-24 h-24 rounded-full bg-white"
78+
className="max-w-none max-h-full"
79+
style={{
80+
width: "auto",
81+
height: "100%",
82+
}}
4583
/>
46-
</figure>
84+
</div>
4785
</div>
4886
</div>
4987

5088
{/* Info */}
5189
<div className="pt-10 mt-2 pb-4 px-4 text-center">
5290
<div className="text-neutral-0 font-semibold text-lg leading-tight group-hover:text-primary-40">
53-
{name} {surname}
91+
<NameUsers
92+
classProps={
93+
"font-semibold text-lg leading-tight group-hover:text-primary-40 "
94+
}
95+
user={developer}
96+
/>
5497
</div>
5598

5699
{/* Profesión + años de experiencia */}
@@ -64,37 +107,26 @@ export const TalentsCard = ({
64107
)}
65108
</div>
66109

67-
<div className="flex gap-1 mt-4 justify-center flex-wrap max-w-full">
68-
{skills.length > 0 && (
69-
<>
70-
{(() => {
71-
// Calcular si las dos primeras skills son demasiado largas
72-
const limitLength = 10; // ajustable
73-
const shortSkills = skills
74-
.slice(0, 3)
75-
.filter((s) => s.length <= limitLength);
76-
const displayedSkills =
77-
shortSkills.length < 3
78-
? skills.slice(0, 2)
79-
: skills.slice(0, 3);
80-
81-
return displayedSkills.map((skill, index) => (
82-
<span
83-
key={index}
84-
className="bg-primary-70 text-neutral-00 px-2 py-0.5 rounded-full text-xs whitespace-nowrap items-center flex"
85-
>
86-
{skill}
87-
</span>
88-
));
89-
})()}
90-
{skills.length > 3 && (
91-
<span className="bg-neutral-60 text-neutral-30 px-2 py-0.5 rounded-full text-sm">
92-
+{skills.length - 3}
93-
</span>
94-
)}
95-
</>
110+
<div
111+
className="flex gap-1 mt-4 justify-center flex-nowrap overflow-hidden max-w-full"
112+
ref={skillsContainerRef}
113+
>
114+
{visibleSkills.length > 0 &&
115+
visibleSkills.map((skill, index) => (
116+
<span
117+
key={index}
118+
className="bg-primary-70 text-neutral-00 px-2 py-0.5 rounded-full text-xs whitespace-nowrap items-center flex"
119+
>
120+
{skill}
121+
</span>
122+
))}
123+
{skills.length > visibleSkills.length && (
124+
<span className="bg-neutral-60 text-neutral-30 px-2 py-0.5 rounded-full text-sm">
125+
+{skills.length - visibleSkills.length}
126+
</span>
96127
)}
97128
</div>
129+
98130
{/* Location */}
99131
{location && (
100132
<div className="text-center text-neutral-20 text-sm mt-4 flex justify-center items-center mb-1">

0 commit comments

Comments
 (0)