173 lines
6.2 KiB
JavaScript
173 lines
6.2 KiB
JavaScript
import { useState, useEffect } from 'react'
|
||
import { getDuplicates, mergeGuests } from '../api/api'
|
||
import './DuplicateManager.css'
|
||
|
||
function DuplicateManager({ eventId, onUpdate, onClose }) {
|
||
const [duplicates, setDuplicates] = useState([])
|
||
const [loading, setLoading] = useState(true)
|
||
const [selectedKeep, setSelectedKeep] = useState({})
|
||
const [merging, setMerging] = useState(false)
|
||
const [duplicateBy, setDuplicateBy] = useState('phone') // 'phone' or 'name'
|
||
|
||
useEffect(() => {
|
||
loadDuplicates()
|
||
}, [duplicateBy])
|
||
|
||
const loadDuplicates = async () => {
|
||
try {
|
||
setLoading(true)
|
||
const response = await getDuplicates(eventId, duplicateBy)
|
||
setDuplicates(response.duplicates || [])
|
||
} catch (error) {
|
||
console.error('Error loading duplicates:', error)
|
||
alert('שגיאה בטעינת כפילויות')
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
const handleMerge = async (key, guests) => {
|
||
const keepId = selectedKeep[key]
|
||
if (!keepId) {
|
||
alert('אנא בחר איזה אורח לשמור')
|
||
return
|
||
}
|
||
|
||
const mergeIds = guests
|
||
.filter(g => g.id !== keepId)
|
||
.map(g => g.id)
|
||
|
||
if (mergeIds.length === 0) {
|
||
alert('לא נבחרו אורחים למיזוג')
|
||
return
|
||
}
|
||
|
||
if (!window.confirm(`האם למזג ${mergeIds.length} אורחים לאורח הנבחר?`)) {
|
||
return
|
||
}
|
||
|
||
try {
|
||
setMerging(true)
|
||
await mergeGuests(eventId, keepId, mergeIds)
|
||
alert('האורחים מוזגו בהצלחה!')
|
||
await loadDuplicates()
|
||
if (onUpdate) onUpdate()
|
||
} catch (error) {
|
||
console.error('Error merging guests:', error)
|
||
alert('שגיאה במיזוג אורחים')
|
||
} finally {
|
||
setMerging(false)
|
||
}
|
||
}
|
||
|
||
if (loading) {
|
||
return (
|
||
<div className="duplicate-manager">
|
||
<div className="duplicate-header">
|
||
<h2>🔍 ניהול כפילויות</h2>
|
||
<button className="btn-close" onClick={onClose}>✕</button>
|
||
</div>
|
||
<div className="duplicate-controls">
|
||
<label>חפש כפילויות לפי:</label>
|
||
<select value={duplicateBy} onChange={(e) => setDuplicateBy(e.target.value)}>
|
||
<option value="phone">מספר טלפון</option>
|
||
<option value="name">שם מלא</option>
|
||
</select>
|
||
</div>
|
||
<div className="loading">טוען כפילויות...</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
if (duplicates.length === 0) {
|
||
return (
|
||
<div className="duplicate-manager">
|
||
<div className="duplicate-header">
|
||
<h2>🔍 ניהול כפילויות</h2>
|
||
<button className="btn-close" onClick={onClose}>✕</button>
|
||
</div>
|
||
<div className="duplicate-controls">
|
||
<label>חפש כפילויות לפי:</label>
|
||
<select value={duplicateBy} onChange={(e) => setDuplicateBy(e.target.value)}>
|
||
<option value="phone">מספר טלפון</option>
|
||
<option value="name">שם מלא</option>
|
||
</select>
|
||
</div>
|
||
<div className="no-duplicates">
|
||
<p>✅ לא נמצאו כפילויות! כל האורחים ייחודיים.</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="duplicate-manager" dir="rtl">
|
||
<div className="duplicate-header">
|
||
<h2>🔍 ניהול כפילויות ({duplicates.length} {duplicateBy === 'phone' ? 'מספרי טלפון' : 'שמות'})</h2>
|
||
<button className="btn-close" onClick={onClose}>✕</button>
|
||
</div>
|
||
|
||
<div className="duplicate-controls">
|
||
<label>חפש כפילויות לפי:</label>
|
||
<select value={duplicateBy} onChange={(e) => setDuplicateBy(e.target.value)}>
|
||
<option value="phone">מספר טלפון</option>
|
||
<option value="name">שם מלא</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="duplicates-list">
|
||
{duplicates.map((dup, index) => (
|
||
<div key={index} className="duplicate-group">
|
||
<div className="duplicate-info">
|
||
<h3>{duplicateBy === 'phone' ? `📞 ${dup.phone_number}` : `👤 ${dup.first_name} ${dup.last_name}`}</h3>
|
||
<span className="count-badge">{dup.count} אורחים</span>
|
||
</div>
|
||
|
||
<div className="guests-grid">
|
||
{dup.guests.map((guest) => (
|
||
<div
|
||
key={guest.id}
|
||
className={`guest-card ${selectedKeep[dup.key] === guest.id ? 'selected' : ''}`}
|
||
onClick={() => setSelectedKeep({...selectedKeep, [dup.key]: guest.id})}
|
||
>
|
||
<div className="radio-wrapper">
|
||
<input
|
||
type="radio"
|
||
name={`keep-${dup.key}`}
|
||
checked={selectedKeep[dup.key] === guest.id}
|
||
onChange={() => setSelectedKeep({...selectedKeep, [dup.key]: guest.id})}
|
||
/>
|
||
<label>שמור אורח זה</label>
|
||
</div>
|
||
<div className="guest-details">
|
||
<h4>{guest.first_name} {guest.last_name}</h4>
|
||
<p><strong>אימייל:</strong> {guest.email || '-'}</p>
|
||
<p><strong>טלפון:</strong> {guest.phone_number || '-'}</p>
|
||
<p><strong>אישור:</strong> {guest.rsvp_status}</p>
|
||
<p><strong>ארוחה:</strong> {guest.meal_preference || '-'}</p>
|
||
<p><strong>פלאס ואן:</strong> {guest.has_plus_one ? `כן${guest.plus_one_name ? ` (${guest.plus_one_name})` : ''}` : 'לא'}</p>
|
||
<p><strong>שולחן:</strong> {guest.table_number || '-'}</p>
|
||
<p className="owner-tag"><strong>מקור:</strong> {guest.owner || '-'}</p>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
<div className="merge-actions">
|
||
<button
|
||
className="btn btn-primary"
|
||
onClick={() => handleMerge(dup.key, dup.guests)}
|
||
disabled={!selectedKeep[dup.key] || merging}
|
||
>
|
||
{merging ? 'ממזג...' : `🔗 מזג אורחים`}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default DuplicateManager
|