diff --git a/client/src/components/EmployeeNotes.jsx b/client/src/components/EmployeeNotes.jsx new file mode 100644 index 0000000..26cf619 --- /dev/null +++ b/client/src/components/EmployeeNotes.jsx @@ -0,0 +1,146 @@ +import React, { useState } from 'react'; +import axios from 'axios'; + +const s = { + wrapper: { marginTop: '20px' }, + sectionHd: { + fontSize: '13px', fontWeight: 700, color: '#f8f9fa', textTransform: 'uppercase', + letterSpacing: '0.5px', marginBottom: '8px', + }, + display: { + background: '#181924', border: '1px solid #2a2b3a', borderRadius: '6px', + padding: '10px 12px', fontSize: '13px', color: '#f8f9fa', minHeight: '36px', + cursor: 'pointer', position: 'relative', + }, + displayEmpty: { + color: '#555770', fontStyle: 'italic', + }, + editHint: { + position: 'absolute', right: '8px', top: '8px', + fontSize: '10px', color: '#555770', + }, + textarea: { + width: '100%', background: '#0d1117', border: '1px solid #4d6fa8', + borderRadius: '6px', color: '#f8f9fa', fontSize: '13px', + padding: '10px 12px', resize: 'vertical', minHeight: '80px', + boxSizing: 'border-box', fontFamily: 'inherit', outline: 'none', + }, + actions: { display: 'flex', gap: '8px', marginTop: '8px' }, + saveBtn: { + background: '#1a3a6b', border: '1px solid #4d6fa8', color: '#90caf9', + borderRadius: '5px', padding: '5px 14px', fontSize: '12px', + cursor: 'pointer', fontWeight: 600, + }, + cancelBtn: { + background: 'none', border: '1px solid #444', color: '#888', + borderRadius: '5px', padding: '5px 14px', fontSize: '12px', + cursor: 'pointer', + }, + saving: { fontSize: '12px', color: '#9ca0b8', alignSelf: 'center' }, + tagRow: { display: 'flex', flexWrap: 'wrap', gap: '6px', marginBottom: '8px' }, + tag: { + display: 'inline-block', padding: '2px 8px', borderRadius: '10px', + fontSize: '11px', fontWeight: 600, background: '#1a2a3a', + color: '#90caf9', border: '1px solid #2a3a5a', cursor: 'default', + }, +}; + +// Quick-add tags for common HR flags +const QUICK_TAGS = ['On PIP', 'Union member', 'Probationary', 'Pending investigation', 'FMLA', 'ADA']; + +export default function EmployeeNotes({ employeeId, initialNotes, onSaved }) { + const [editing, setEditing] = useState(false); + const [draft, setDraft] = useState(initialNotes || ''); + const [saved, setSaved] = useState(initialNotes || ''); + const [saving, setSaving] = useState(false); + + const handleSave = async () => { + setSaving(true); + try { + await axios.patch(`/api/employees/${employeeId}/notes`, { notes: draft }); + setSaved(draft); + setEditing(false); + if (onSaved) onSaved(draft); + } finally { + setSaving(false); + } + }; + + const handleCancel = () => { + setDraft(saved); + setEditing(false); + }; + + const addTag = (tag) => { + const current = draft.trim(); + // Don't add a tag that's already present + if (current.includes(tag)) return; + setDraft(current ? `${current}\n${tag}` : tag); + }; + + // Parse saved notes into display lines + const lines = saved ? saved.split('\n').filter(Boolean) : []; + + return ( +