mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-03 20:12:59 +00:00
re
This commit is contained in:
@@ -50,12 +50,14 @@ type GeoCoords struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Reservation struct {
|
type Reservation struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
DriverName string `json:"driverName"`
|
DriverName string `json:"driverName"`
|
||||||
Vehicle string `json:"vehicle"`
|
Vehicle string `json:"vehicle"`
|
||||||
StartDateTime time.Time `json:"startDateTime"`
|
StartDate string `json:"startDate"`
|
||||||
EndDateTime time.Time `json:"endDateTime"`
|
StartTime string `json:"startTime"`
|
||||||
Purpose string `json:"purpose"`
|
EndDate string `json:"endDate"`
|
||||||
|
EndTime string `json:"endTime"`
|
||||||
|
Purpose string `json:"purpose,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -320,14 +322,39 @@ func handleCreateReservation(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only validate required fields (purpose is now optional)
|
// Validate required fields
|
||||||
if reservation.DriverName == "" || reservation.Vehicle == "" {
|
if reservation.DriverName == "" || reservation.Vehicle == "" ||
|
||||||
http.Error(w, "Driver name and vehicle are required", http.StatusBadRequest)
|
reservation.StartDate == "" || reservation.StartTime == "" ||
|
||||||
|
reservation.EndDate == "" || reservation.EndTime == "" {
|
||||||
|
http.Error(w, "Missing required fields", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create combined date-time string
|
||||||
|
startDateTime, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", reservation.StartDate, reservation.StartTime))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid start date/time", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
endDateTime, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", reservation.EndDate, reservation.EndTime))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid end date/time", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate time order
|
||||||
|
if endDateTime.Before(startDateTime) {
|
||||||
|
http.Error(w, "End time must be after start time", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate unique ID
|
||||||
reservation.ID = fmt.Sprintf("res_%d", time.Now().UnixNano())
|
reservation.ID = fmt.Sprintf("res_%d", time.Now().UnixNano())
|
||||||
|
|
||||||
|
// Save reservation
|
||||||
reservations, err := loadReservations()
|
reservations, err := loadReservations()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to load reservations", http.StatusInternalServerError)
|
http.Error(w, "Failed to load reservations", http.StatusInternalServerError)
|
||||||
@@ -347,18 +374,23 @@ func handleCreateReservation(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func handleCheckAvailability(w http.ResponseWriter, r *http.Request) {
|
func handleCheckAvailability(w http.ResponseWriter, r *http.Request) {
|
||||||
vehicle := r.URL.Query().Get("vehicle")
|
vehicle := r.URL.Query().Get("vehicle")
|
||||||
startStr := r.URL.Query().Get("start")
|
startDate := r.URL.Query().Get("startDate")
|
||||||
endStr := r.URL.Query().Get("end")
|
startTime := r.URL.Query().Get("startTime")
|
||||||
|
endDate := r.URL.Query().Get("endDate")
|
||||||
|
endTime := r.URL.Query().Get("endTime")
|
||||||
|
|
||||||
start, err := time.Parse(time.RFC3339, startStr)
|
// Parse combined date and time strings
|
||||||
|
startDateTime, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", startDate, startTime))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Invalid start time", http.StatusBadRequest)
|
http.Error(w, "Invalid start date/time", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
end, err := time.Parse(time.RFC3339, endStr)
|
endDateTime, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", endDate, endTime))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Invalid end time", http.StatusBadRequest)
|
http.Error(w, "Invalid end date/time", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +403,21 @@ func handleCheckAvailability(w http.ResponseWriter, r *http.Request) {
|
|||||||
available := true
|
available := true
|
||||||
for _, res := range reservations {
|
for _, res := range reservations {
|
||||||
if res.Vehicle == vehicle {
|
if res.Vehicle == vehicle {
|
||||||
if start.Before(res.EndDateTime) && end.After(res.StartDateTime) {
|
// Parse reservation dates
|
||||||
|
resStart, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", res.StartDate, res.StartTime))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resEnd, err := time.Parse("2006-01-02 15:04",
|
||||||
|
fmt.Sprintf("%s %s", res.EndDate, res.EndTime))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for overlap
|
||||||
|
if startDateTime.Before(resEnd) && endDateTime.After(resStart) {
|
||||||
available = false
|
available = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-13
@@ -297,16 +297,70 @@
|
|||||||
|
|
||||||
<!-- Date and Time Selection -->
|
<!-- Date and Time Selection -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<!-- Start Date and Time -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="startDateTime">Začátek</label>
|
<label for="startDate">Datum začátku</label>
|
||||||
<input type="datetime-local" id="startDateTime" name="startDateTime" required
|
<input type="date" id="startDate" name="startDate" required
|
||||||
class="w-full p-2 border border-gray-300 rounded-md">
|
class="w-full p-2 border border-gray-300 rounded-md">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="endDateTime">Konec</label>
|
<label for="startTime">Čas začátku</label>
|
||||||
<input type="datetime-local" id="endDateTime" name="endDateTime" required
|
<select id="startTime" name="startTime" required
|
||||||
class="w-full p-2 border border-gray-300 rounded-md">
|
class="w-full p-2 border border-gray-300 rounded-md">
|
||||||
|
<option value="">Vyberte čas</option>
|
||||||
|
<option value="06:00">06:00</option>
|
||||||
|
<option value="07:00">07:00</option>
|
||||||
|
<option value="08:00">08:00</option>
|
||||||
|
<option value="09:00">09:00</option>
|
||||||
|
<option value="10:00">10:00</option>
|
||||||
|
<option value="11:00">11:00</option>
|
||||||
|
<option value="12:00">12:00</option>
|
||||||
|
<option value="13:00">13:00</option>
|
||||||
|
<option value="14:00">14:00</option>
|
||||||
|
<option value="15:00">15:00</option>
|
||||||
|
<option value="16:00">16:00</option>
|
||||||
|
<option value="17:00">17:00</option>
|
||||||
|
<option value="18:00">18:00</option>
|
||||||
|
<option value="19:00">19:00</option>
|
||||||
|
<option value="20:00">20:00</option>
|
||||||
|
<option value="21:00">21:00</option>
|
||||||
|
<option value="22:00">22:00</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<!-- End Date and Time -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="endDate">Datum konce</label>
|
||||||
|
<input type="date" id="endDate" name="endDate" required
|
||||||
|
class="w-full p-2 border border-gray-300 rounded-md">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="endTime">Čas konce</label>
|
||||||
|
<select id="endTime" name="endTime" required
|
||||||
|
class="w-full p-2 border border-gray-300 rounded-md">
|
||||||
|
<option value="">Vyberte čas</option>
|
||||||
|
<option value="06:00">06:00</option>
|
||||||
|
<option value="07:00">07:00</option>
|
||||||
|
<option value="08:00">08:00</option>
|
||||||
|
<option value="09:00">09:00</option>
|
||||||
|
<option value="10:00">10:00</option>
|
||||||
|
<option value="11:00">11:00</option>
|
||||||
|
<option value="12:00">12:00</option>
|
||||||
|
<option value="13:00">13:00</option>
|
||||||
|
<option value="14:00">14:00</option>
|
||||||
|
<option value="15:00">15:00</option>
|
||||||
|
<option value="16:00">16:00</option>
|
||||||
|
<option value="17:00">17:00</option>
|
||||||
|
<option value="18:00">18:00</option>
|
||||||
|
<option value="19:00">19:00</option>
|
||||||
|
<option value="20:00">20:00</option>
|
||||||
|
<option value="21:00">21:00</option>
|
||||||
|
<option value="22:00">22:00</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -332,6 +386,14 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<!-- Status message container -->
|
||||||
|
<div class="mt-4 p-4 rounded-md hidden" id="statusMessage">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<i id="messageIcon" class="mr-2"></i>
|
||||||
|
<span id="messageText"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -471,18 +533,24 @@
|
|||||||
reservationForm.addEventListener('submit', async function(e) {
|
reservationForm.addEventListener('submit', async function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Validate dates
|
const startDate = document.getElementById('startDate').value;
|
||||||
const startDate = new Date(document.getElementById('startDateTime').value);
|
const startTime = document.getElementById('startTime').value;
|
||||||
const endDate = new Date(document.getElementById('endDateTime').value);
|
const endDate = document.getElementById('endDate').value;
|
||||||
|
const endTime = document.getElementById('endTime').value;
|
||||||
|
|
||||||
if (endDate <= startDate) {
|
// Create ISO datetime strings
|
||||||
showMessage('Čas ukončení musí být později než čas začátku', 'error');
|
const startDateTime = new Date(`${startDate}T${startTime}`);
|
||||||
|
const endDateTime = new Date(`${endDate}T${endTime}`);
|
||||||
|
|
||||||
|
// Validate dates
|
||||||
|
if (endDateTime <= startDateTime) {
|
||||||
|
showMessage('Konec musí být později než začátek', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check vehicle availability
|
// Check vehicle availability
|
||||||
const vehicle = document.getElementById('vehicle').value;
|
const vehicle = document.getElementById('vehicle').value;
|
||||||
const isAvailable = await checkVehicleAvailability(vehicle, startDate, endDate);
|
const isAvailable = await checkVehicleAvailability(vehicle, startDateTime, endDateTime);
|
||||||
|
|
||||||
if (!isAvailable) {
|
if (!isAvailable) {
|
||||||
showMessage('Vozidlo není v tomto čase dostupné', 'error');
|
showMessage('Vozidlo není v tomto čase dostupné', 'error');
|
||||||
@@ -493,8 +561,8 @@
|
|||||||
const reservationData = {
|
const reservationData = {
|
||||||
driverName: document.getElementById('driverName').value,
|
driverName: document.getElementById('driverName').value,
|
||||||
vehicle: vehicle,
|
vehicle: vehicle,
|
||||||
startDateTime: startDate.toISOString(),
|
startDateTime: startDateTime.toISOString(),
|
||||||
endDateTime: endDate.toISOString(),
|
endDateTime: endDateTime.toISOString(),
|
||||||
purpose: document.getElementById('purpose').value
|
purpose: document.getElementById('purpose').value
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -519,6 +587,32 @@
|
|||||||
showMessage(error.message || 'Nepodařilo se vytvořit rezervaci', 'error');
|
showMessage(error.message || 'Nepodařilo se vytvořit rezervaci', 'error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Populate time dropdowns with full hours
|
||||||
|
function populateTimeDropdowns() {
|
||||||
|
const timeSelects = [document.getElementById('startTime'), document.getElementById('endTime')];
|
||||||
|
|
||||||
|
for (let hour = 6; hour <= 22; hour++) { // 6:00 to 22:00
|
||||||
|
const hourStr = hour.toString().padStart(2, '0');
|
||||||
|
const timeStr = `${hourStr}:00`;
|
||||||
|
const option = new Option(timeStr, timeStr);
|
||||||
|
|
||||||
|
timeSelects.forEach(select => {
|
||||||
|
select.appendChild(option.cloneNode(true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize time dropdowns when page loads
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
populateTimeDropdowns();
|
||||||
|
|
||||||
|
// Set default dates to today
|
||||||
|
const today = new Date();
|
||||||
|
const dateStr = today.toISOString().split('T')[0];
|
||||||
|
document.getElementById('startDate').value = dateStr;
|
||||||
|
document.getElementById('endDate').value = dateStr;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user