main page
This commit is contained in:
333
src/components/CreateTicketModal.jsx
Normal file
333
src/components/CreateTicketModal.jsx
Normal file
@@ -0,0 +1,333 @@
|
||||
import { useState } from 'react'
|
||||
import { FaTimes } from 'react-icons/fa'
|
||||
|
||||
const TICKET_TYPES = [
|
||||
'Home Office', 'Holidays', 'Trip', 'Supportrequest', 'Change Request',
|
||||
'Maintenance', 'Project', 'Controlling', 'Development', 'Documentation',
|
||||
'Meeting/Conference', 'IT Management', 'IT Security', 'Procurement',
|
||||
'Rollout', 'Emergency Call', 'Other Services'
|
||||
]
|
||||
|
||||
const SYSTEMS = [
|
||||
'Account View', 'Client', 'Cofano', 'Credentials', 'Diamant', 'Docuware',
|
||||
'EDI', 'eMail', 'Employee', 'Invoice', 'LBase', 'Medical Office', 'Network',
|
||||
'O365', 'PDF Viewer', 'Printer', 'Reports', 'Server', 'Time Tracking',
|
||||
'TK', 'TOS', 'Vivendi NG', 'VGM', '(W)LAN', '(W)WAN', 'WOMS', 'n/a'
|
||||
]
|
||||
|
||||
const RESPONSE_LEVELS = [
|
||||
'USER', 'KEY USER', 'Helpdesk', 'Support', 'Admin', 'FS/FE', '24/7',
|
||||
'TECH MGMT', 'Backoffice', 'BUSI MGMT', 'n/a'
|
||||
]
|
||||
|
||||
const SERVICE_TYPES = ['Remote', 'On Site', 'Off Site']
|
||||
|
||||
const PRIORITIES = [
|
||||
{ value: 0, label: 'None' },
|
||||
{ value: 1, label: 'Low' },
|
||||
{ value: 2, label: 'Medium' },
|
||||
{ value: 3, label: 'High' },
|
||||
{ value: 4, label: 'Critical' }
|
||||
]
|
||||
|
||||
const today = new Date().toLocaleDateString('de-DE')
|
||||
|
||||
export default function CreateTicketModal({ isOpen, onClose, onCreate, customers = [] }) {
|
||||
const [formData, setFormData] = useState({
|
||||
customerId: '',
|
||||
type: 'Supportrequest',
|
||||
systemType: '',
|
||||
responseLevel: '',
|
||||
serviceType: 'Remote',
|
||||
priority: 1,
|
||||
topic: '',
|
||||
requestedBy: '',
|
||||
requestedFor: '',
|
||||
startDate: today,
|
||||
startTime: '',
|
||||
deadline: today,
|
||||
endTime: '',
|
||||
estimate: '30',
|
||||
mailCopyTo: '',
|
||||
sendNotification: false,
|
||||
details: ''
|
||||
})
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const handleChange = (field, value) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }))
|
||||
}
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault()
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
await onCreate(formData)
|
||||
onClose()
|
||||
setFormData({
|
||||
customerId: '',
|
||||
type: 'Supportrequest',
|
||||
systemType: '',
|
||||
responseLevel: '',
|
||||
serviceType: 'Remote',
|
||||
priority: 1,
|
||||
topic: '',
|
||||
requestedBy: '',
|
||||
requestedFor: '',
|
||||
startDate: today,
|
||||
startTime: '',
|
||||
deadline: today,
|
||||
endTime: '',
|
||||
estimate: '30',
|
||||
mailCopyTo: '',
|
||||
sendNotification: false,
|
||||
details: ''
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error creating ticket:', error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOpen) return null
|
||||
|
||||
return (
|
||||
<div className="overlay">
|
||||
<span className="overlay-close" onClick={onClose}>
|
||||
<FaTimes />
|
||||
</span>
|
||||
<div className="overlay-content">
|
||||
<h2 className="mb-2">Create New Ticket</h2>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="row">
|
||||
<div className="col col-6">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Customer ID</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.customerId}
|
||||
onChange={(e) => handleChange('customerId', e.target.value)}
|
||||
required
|
||||
>
|
||||
<option value="">Affected Customer</option>
|
||||
{customers.map(c => (
|
||||
<option key={c.id} value={c.id}>({c.code}) {c.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Work Order Type</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.type}
|
||||
onChange={(e) => handleChange('type', e.target.value)}
|
||||
>
|
||||
{TICKET_TYPES.map(type => (
|
||||
<option key={type} value={type}>{type}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Affected System</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.systemType}
|
||||
onChange={(e) => handleChange('systemType', e.target.value)}
|
||||
required
|
||||
>
|
||||
<option value="">Affected System</option>
|
||||
{SYSTEMS.map(sys => (
|
||||
<option key={sys} value={sys}>{sys}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Response Level</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.responseLevel}
|
||||
onChange={(e) => handleChange('responseLevel', e.target.value)}
|
||||
>
|
||||
<option value="">Response Level</option>
|
||||
{RESPONSE_LEVELS.map(level => (
|
||||
<option key={level} value={level}>{level}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Service Type</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.serviceType}
|
||||
onChange={(e) => handleChange('serviceType', e.target.value)}
|
||||
>
|
||||
{SERVICE_TYPES.map(type => (
|
||||
<option key={type} value={type}>{type}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Priority</label>
|
||||
<select
|
||||
className="form-control"
|
||||
value={formData.priority}
|
||||
onChange={(e) => handleChange('priority', parseInt(e.target.value))}
|
||||
required
|
||||
>
|
||||
<option value="">Priority Level</option>
|
||||
{PRIORITIES.map(p => (
|
||||
<option key={p.value} value={p.value}>{p.label}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col col-6">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Topic</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="Topic"
|
||||
value={formData.topic}
|
||||
onChange={(e) => handleChange('topic', e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Requested by</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="Name"
|
||||
value={formData.requestedBy}
|
||||
onChange={(e) => handleChange('requestedBy', e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Requested for</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="Name"
|
||||
value={formData.requestedFor}
|
||||
onChange={(e) => handleChange('requestedFor', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Start Date & Time</label>
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="dd.mm.yyyy"
|
||||
value={formData.startDate}
|
||||
onChange={(e) => handleChange('startDate', e.target.value)}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="hhmm"
|
||||
value={formData.startTime}
|
||||
onChange={(e) => handleChange('startTime', e.target.value)}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">End Date & Time (Deadline)</label>
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="dd.mm.yyyy"
|
||||
value={formData.deadline}
|
||||
onChange={(e) => handleChange('deadline', e.target.value)}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="hhmm"
|
||||
value={formData.endTime}
|
||||
onChange={(e) => handleChange('endTime', e.target.value)}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Workload Estimate</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="xx minutes"
|
||||
value={formData.estimate}
|
||||
onChange={(e) => handleChange('estimate', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Notification Recipient(s)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="name@domain.xx"
|
||||
value={formData.mailCopyTo}
|
||||
onChange={(e) => handleChange('mailCopyTo', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={formData.sendNotification}
|
||||
onChange={(e) => handleChange('sendNotification', e.target.checked)}
|
||||
/>
|
||||
Send Notification?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Details</label>
|
||||
<textarea
|
||||
className="form-control"
|
||||
rows={5}
|
||||
placeholder="Details"
|
||||
value={formData.details}
|
||||
onChange={(e) => handleChange('details', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="text-center mt-2">
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-dark"
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? 'Creating...' : 'CREATE NOW'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user