diff --git a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx index 3dc4adac29..2534ef4c71 100644 --- a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx +++ b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.jsx @@ -1,17 +1,84 @@ -import React from 'react'; +import PropTypes from 'prop-types'; +import { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { toast } from 'react-toastify'; import styles from './TeamCard.module.css'; import { TeamMemberRow } from './TeamMemberRow'; +function ConfirmModal({ action, count, onConfirm, onCancel }) { + return ( +
+
+

Confirm Action

+

+ Are you sure you want to {action} to {count} member + {count > 1 ? 's' : ''}? +

+
+ + +
+
+
+ ); +} + +ConfirmModal.propTypes = { + action: PropTypes.string.isRequired, + count: PropTypes.number.isRequired, + onConfirm: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +}; + export default function TeamCard() { const teamMembers = [ - { name: 'Shreya Laheri', score: '9/10' }, - { name: 'Shreya Vithala', score: '7/10' }, - { name: 'Jae Sabol', score: '5/10' }, - { name: 'Sara Sabol', score: '2/10' }, + { id: 1, name: 'Shreya Laheri', score: '9/10' }, + { id: 2, name: 'Shreya Vithala', score: '7/10' }, + { id: 3, name: 'Jae Sabol', score: '5/10' }, + { id: 4, name: 'Sara Sabol', score: '2/10' }, ]; + const darkMode = useSelector(state => state.theme.darkMode); + const [selectedMembers, setSelectedMembers] = useState([]); + const [confirmAction, setConfirmAction] = useState(null); + + const toggleSelect = id => { + setSelectedMembers(prev => (prev.includes(id) ? prev.filter(m => m !== id) : [...prev, id])); + }; + + const handleBulkAction = action => { + setConfirmAction(action); + }; + + const handleConfirm = () => { + // TODO: wire up real API calls when backend is ready + if (confirmAction === 'Send Message') { + toast.success( + `Message sent to ${selectedMembers.length} member${selectedMembers.length > 1 ? 's' : ''}!`, + ); + } else if (confirmAction === 'Request Skill Update') { + toast.success( + `Skill update requested for ${selectedMembers.length} member${ + selectedMembers.length > 1 ? 's' : '' + }!`, + ); + } + setSelectedMembers([]); + setConfirmAction(null); + }; + + const handleCancel = () => { + setConfirmAction(null); + }; + + const noneSelected = selectedMembers.length === 0; + return ( - <> +

@@ -33,12 +100,47 @@ export default function TeamCard() { Your Team_______ rating

+ + {/* Bulk Action Bar */} +
+ + {noneSelected + ? 'No members selected' + : `${selectedMembers.length} member${selectedMembers.length > 1 ? 's' : ''} selected`} + +
+ + +
+
+ + {/* Member Rows */}
- {teamMembers.map((member, index) => ( - + {teamMembers.map(member => ( + ))}
+
Show your team member @@ -47,6 +149,17 @@ export default function TeamCard() {
- + + {/* Confirmation Modal */} + {confirmAction && ( + + )} +
); } diff --git a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css index 41dac9a5ef..242c3cc4b8 100644 --- a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css +++ b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamCard.module.css @@ -1,6 +1,13 @@ +.teamCardWrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 60vh; +} + .teamCardContainer { width: 580px; - height: 449px; display: flex; flex-direction: column; border-radius: 20px; @@ -18,8 +25,8 @@ .teamCardTitle { display: flex; - align-items: center; /* This will vertically align the icon and text */ - gap: 8px; /* This adds some space between the icon and the text */ + align-items: center; + gap: 8px; color: #6e6e6e; font-family: Inter, sans-serif; font-size: 24px; @@ -36,16 +43,77 @@ color: #6e6e6e; } +/* ── Bulk Action Bar ── */ +.bulkActionBar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 12px; + margin: 0 0 8px 0; + border: 1px solid #adb5bd; + border-radius: 8px; + background: transparent; +} + +.selectedCount { + font-size: 14px; + font-weight: 500; + color: inherit; +} + +.bulkButtons { + display: flex; + gap: 8px; +} + +.bulkBtn { + padding: 7px 14px; + border: none; + border-radius: 4px; + background: #007bff; + color: #fff; + font-size: 13px; + cursor: pointer; + transition: background 0.2s; +} + +.bulkBtn:hover:not(:disabled) { + background: #0056b3; +} + +.bulkBtn:disabled { + background: #adb5bd; + cursor: not-allowed; + opacity: 0.7; +} + +/* ── Member Row ── */ .teamMemberRow { padding: 12px; display: flex; align-items: center; justify-content: space-between; + border-radius: 8px; + transition: background 0.2s; +} + +.teamMemberRowSelected { + background: rgba(0, 123, 255, 0.08); +} + +.memberCheckbox { + width: 18px; + height: 18px; + margin-right: 12px; + cursor: pointer; + accent-color: #007bff; + flex-shrink: 0; } .teamMemberInfo { display: flex; align-items: center; + flex: 1; } .teamMemberName { @@ -106,3 +174,88 @@ display: flex; justify-content: space-evenly; } + +/* ── Confirmation Modal ── */ +.modalOverlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal { + background: #fff; + border-radius: 8px; + padding: 28px 32px; + width: 380px; + max-width: 90%; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + text-align: center; +} + +.modalTitle { + margin: 0 0 12px 0; + font-size: 1.2rem; + font-family: Inter, sans-serif; + color: #000; +} + +.modalText { + font-size: 15px; + margin-bottom: 24px; + font-family: Inter, sans-serif; + color: #333; +} + +.modalActions { + display: flex; + gap: 12px; + justify-content: center; +} + +.confirmBtn { + padding: 9px 20px; + background: #007bff; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + transition: background 0.2s; +} + +.confirmBtn:hover { + background: #0056b3; +} + +.cancelBtn { + padding: 9px 20px; + background: #6c757d; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + transition: background 0.2s; +} + +.cancelBtn:hover { + background: #5a6268; +} + +@media (prefers-color-scheme: dark) { + .modal { + background: #2b2b2b; + } + + .modalTitle { + color: #fff; + } + + .modalText { + color: #ccc; + } +} \ No newline at end of file diff --git a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamMemberRow.jsx b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamMemberRow.jsx index 216de47794..f1a7e3d5f1 100644 --- a/src/components/HGNHelpSkillsDashboard/TeamCard/TeamMemberRow.jsx +++ b/src/components/HGNHelpSkillsDashboard/TeamCard/TeamMemberRow.jsx @@ -1,17 +1,24 @@ -import React from 'react'; import { Mail } from 'lucide-react'; +import PropTypes from 'prop-types'; import { SlackIcon } from './SlackIcon'; import styles from './TeamCard.module.css'; -export const TeamMemberRow = ({ member }) => { +export const TeamMemberRow = ({ member, isSelected, onToggleSelect }) => { const getScoreStyle = score => { - const scoreNum = parseInt(score); + const scoreNum = parseInt(score, 10); const scoreColor = scoreNum >= 5 ? styles.scoreGreen : styles.scoreRed; return `${styles.scoreBase} ${scoreColor}`; }; return ( -
+
+ onToggleSelect(member.id)} + aria-label={`Select ${member.name}`} + />
{member.name}
@@ -23,3 +30,13 @@ export const TeamMemberRow = ({ member }) => {
); }; + +TeamMemberRow.propTypes = { + member: PropTypes.shape({ + id: PropTypes.number.isRequired, + name: PropTypes.string.isRequired, + score: PropTypes.string.isRequired, + }).isRequired, + isSelected: PropTypes.bool.isRequired, + onToggleSelect: PropTypes.func.isRequired, +};