initial logic shift from PHP to JS
This commit is contained in:
parent
ed3d229c8f
commit
5565e7902b
2 changed files with 129 additions and 123 deletions
|
|
@ -0,0 +1,86 @@
|
|||
const petCategory = ["Dog", "Cat", "Bird", "Fish", "Reptile", "Other"];
|
||||
const musicGenre = ["Pop", "Rock", "Classical", "Jazz", "Country", "Electronic", "Other"];
|
||||
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('petSongForm', () => ({
|
||||
petCategory: petCategory,
|
||||
musicGenre: musicGenre,
|
||||
isCropping: false,
|
||||
isSubmitting: false,
|
||||
cropper: null,
|
||||
formData: {
|
||||
petName: '',
|
||||
petType: '',
|
||||
musicVibe: '',
|
||||
yourName: '',
|
||||
croppedImage: ''
|
||||
},
|
||||
init() {
|
||||
// Listen for file selection
|
||||
const fileInput = document.getElementById('image');
|
||||
fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
|
||||
},
|
||||
|
||||
handleFileSelect(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
this.isCropping = true;
|
||||
const cropperImg = document.getElementById('cropper-image');
|
||||
cropperImg.src = event.target.result;
|
||||
|
||||
if (this.cropper) this.cropper.destroy();
|
||||
this.cropper = new Cropper(cropperImg, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 1,
|
||||
autoCropArea: 1
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
|
||||
acceptCrop() {
|
||||
const canvas = this.cropper.getCroppedCanvas({ width: 600, height: 600 });
|
||||
this.formData.croppedImage = canvas.toDataURL('image/jpeg', 0.9);
|
||||
|
||||
document.getElementById('preview-image').src = this.formData.croppedImage;
|
||||
this.isCropping = false;
|
||||
this.cropper.destroy();
|
||||
this.cropper = null;
|
||||
},
|
||||
|
||||
cancelCrop() {
|
||||
document.getElementById('image').value = '';
|
||||
this.isCropping = false;
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy();
|
||||
this.cropper = null;
|
||||
}
|
||||
},
|
||||
|
||||
async submitForm() {
|
||||
// Trigger native browser validation bubbles
|
||||
if (!this.$el.checkValidity()) {
|
||||
this.$el.reportValidity();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.formData.croppedImage) {
|
||||
alert("Please upload and accept a photo.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.isSubmitting = true;
|
||||
|
||||
// Mocking API call
|
||||
console.log("Sending JSON data:", JSON.stringify(this.formData));
|
||||
|
||||
setTimeout(() => {
|
||||
this.isSubmitting = false;
|
||||
// window.location.href = 'success.html';
|
||||
}, 1500);
|
||||
}
|
||||
}));
|
||||
});
|
||||
166
index.php
166
index.php
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
$soldPage = true;
|
||||
$soldPage = false;
|
||||
$soldPage = true;
|
||||
$soldPage = false;
|
||||
|
||||
$soldPageDisplay = 'display: none';
|
||||
if($soldPage == true){
|
||||
$soldPageDisplay = 'display: flex';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
|
@ -20,89 +20,85 @@
|
|||
<meta name="description" content="Create a personalized love song for your pet with our fun and easy tool.">
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/cropperjs@1.6.2/dist/cropper.min.css">
|
||||
|
||||
|
||||
<?php include('opengraph.php'); ?>
|
||||
</head>
|
||||
<body>
|
||||
<body x-data="petSongForm">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<?php include('header.php'); ?>
|
||||
|
||||
|
||||
<div class="body-container">
|
||||
|
||||
|
||||
<img class="jukebox-banner-mb" src="assets/images/jukebox-banner-mb.png" alt="Jukebox" />
|
||||
<img class="jukebox-banner-dt" src="assets/images/jukebox-banner-dt.png" alt="Jukebox" />
|
||||
|
||||
|
||||
<div class="title">Let's make your <br/>Pet Love Song.</div>
|
||||
<div class="sub-title">Tell us about your furry, finned, <br/>or feathered Valentine and our <br/>song-maker will do the rest.</div>
|
||||
|
||||
<form method="POST" enctype="multipart/form-data" id="uploadForm">
|
||||
|
||||
|
||||
<form id="uploadForm" @submit.prevent="submitForm">
|
||||
|
||||
<div class="form-row">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="petName">Pet name</label>
|
||||
<input type="text" id="petName" name="petName" pattern="[A-Za-z ]+" minlength="5" maxlength="100" oninput="this.value = this.value.replace(/[^A-Za-z ]/g, '');" required value="<?php echo htmlspecialchars($_POST['petName'] ?? ''); ?>">
|
||||
<input type="text" id="petName" name="petName" x-model="formData.petName" pattern="[A-Za-z ]+" minlength="2" maxlength="100" oninput="this.value = this.value.replace(/[^A-Za-z ]/g, '');" required>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="petType">Pet type</label>
|
||||
<select id="petType" name="petType" class="form-control" required>
|
||||
<option value=""> </option>
|
||||
<option value="Dog" <?php if(($_POST['petType'] ?? '') === 'Dog') echo 'selected'; ?>>Dog</option>
|
||||
<option value="Cat" <?php if(($_POST['petType'] ?? '') === 'Cat') echo 'selected'; ?>>Cat</option>
|
||||
<option value="Bird" <?php if(($_POST['petType'] ?? '') === 'Bird') echo 'selected'; ?>>Bird</option>
|
||||
<option value="Fish" <?php if(($_POST['petType'] ?? '') === 'Fish') echo 'selected'; ?>>Fish</option>
|
||||
<option value="Other" <?php if(($_POST['petType'] ?? '') === 'Other') echo 'selected'; ?>>Other</option>
|
||||
</select>
|
||||
<select id="petType" name="petType" class="form-control" x-model="formData.petType" required>
|
||||
<option value=""></option>
|
||||
<template x-for="type in petCategory" :key="type">
|
||||
<option :value="type" x-text="type"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="file-upload">
|
||||
<input type="file" id="image" name="image" accept="image/jpeg,image/jpg,image/png" required>
|
||||
<label for="image" class="file-upload-label" id="upload-label">
|
||||
<input type="file" id="image" x-ref="imageInput" accept="image/jpeg,image/jpg,image/png" :required="!formData.croppedImage">
|
||||
<label for="image" class="file-upload-label" id="upload-label" x-show="!isCropping && !formData.croppedImage">
|
||||
<div class="file-upload-icon">📷</div>
|
||||
<div class="file-upload-text">Upload a photo or take a pic</div>
|
||||
</label>
|
||||
<!-- START -->
|
||||
<!-- Cropper state (hidden initially) -->
|
||||
<div id="cropper-box" class="file-upload-label" style="display:none; padding: 10px;">
|
||||
<div id="cropper-box" class="file-upload-label" x-show="isCropping" style="display:none; padding: 10px;">
|
||||
<div style="max-width: 100%; max-height: 300px; overflow: hidden;">
|
||||
<img id="cropper-image" src="" style="max-width: 100%;">
|
||||
</div>
|
||||
<div style="margin-top: 10px; display: flex; gap: 10px; justify-content: center;">
|
||||
<button type="button" id="btn-accept" style="background: #00AA28; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">✓ Accept</button>
|
||||
<button type="button" id="btn-cancel" style="background: #666; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">✕ Cancel</button>
|
||||
<button type="button" @click="acceptCrop()" id="btn-accept" style="background: #00AA28; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">✓ Accept</button>
|
||||
<button type="button" @click="cancelCrop()" id="btn-cancel" style="background: #666; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">✕ Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Preview state (hidden initially) -->
|
||||
<div id="preview-box" class="file-upload-label" style="display:none; padding: 10px; cursor: pointer;">
|
||||
<div id="preview-box" @click="$refs.imageInput.click()" class="file-upload-label" x-show="formData.croppedImage && !isCropping" style="display:none; padding: 10px; cursor: pointer;">
|
||||
<img id="preview-image" src="" style="width: 100%; max-width: 300px; border-radius: 4px;">
|
||||
<div style="margin-top: 10px; font-size: 14px;">✎ Click to change photo</div>
|
||||
<div style="margin-top: 10px; font-size: 14px;">Click to change photo</div>
|
||||
</div>
|
||||
<!-- END -->
|
||||
</div>
|
||||
<input type="hidden" name="croppedImage" id="croppedImage">
|
||||
|
||||
<input type="hidden" name="croppedImage" id="croppedImage" x-model="formData.croppedImage">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="musicVibe">Music vibe?</label>
|
||||
<select id="musicVibe" name="musicVibe" class="form-control" required>
|
||||
<option value=""> </option>
|
||||
<option value="Chill" <?php if(($_POST['musicVibe'] ?? '') === 'Chill') echo 'selected'; ?>>Chill</option>
|
||||
<option value="Energetic" <?php if(($_POST['musicVibe'] ?? '') === 'Energetic') echo 'selected'; ?>>Energetic</option>
|
||||
<option value="Romantic" <?php if(($_POST['musicVibe'] ?? '') === 'Romantic') echo 'selected'; ?>>Romantic</option>
|
||||
<option value="Party" <?php if(($_POST['musicVibe'] ?? '') === 'Party') echo 'selected'; ?>>Party</option>
|
||||
<option value="Relaxing" <?php if(($_POST['musicVibe'] ?? '') === 'Relaxing') echo 'selected'; ?>>Relaxing</option>
|
||||
<option value="Other" <?php if(($_POST['musicVibe'] ?? '') === 'Other') echo 'selected'; ?>>Other</option>
|
||||
</select>
|
||||
<select id="musicVibe" name="musicVibe" class="form-control" x-model="formData.musicVibe" required>
|
||||
<option value=""></option>
|
||||
<template x-for="genre in musicGenre" :key="genre">
|
||||
<option :value="genre" x-text="genre"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="yourName">Your name</label>
|
||||
<input type="text" id="yourName" name="yourName" pattern="[A-Za-z ]+" minlength="5" maxlength="100" oninput="this.value = this.value.replace(/[^A-Za-z ]/g, '');" required value="<?php echo htmlspecialchars($_POST['yourName'] ?? ''); ?>">
|
||||
<input type="text" id="yourName" name="yourName" x-model="formData.yourName" pattern="[A-Za-z ]+" minlength="2" maxlength="100" oninput="this.value = this.value.replace(/[^A-Za-z ]/g, '');" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="submit-btn" class="submit-btn">Make my Pet Love Song</button>
|
||||
|
||||
<button type="submit" id="submit-btn" class="submit-btn" :disabled="isSubmitting" x-text="isSubmitting ? 'Creating...' : 'Make my Pet Love Song'">Make my Pet Love Song</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -142,83 +138,7 @@
|
|||
}
|
||||
</style>
|
||||
<script defer src="https://unpkg.com/cropperjs@1.6.2/dist/cropper.min.js"></script>
|
||||
<script defer src="assets/js/home.js"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const fileInput = document.getElementById('image');
|
||||
const uploadLabel = document.getElementById('upload-label');
|
||||
const cropperBox = document.getElementById('cropper-box');
|
||||
const previewBox = document.getElementById('preview-box');
|
||||
const cropperImg = document.getElementById('cropper-image');
|
||||
const previewImg = document.getElementById('preview-image');
|
||||
const btnAccept = document.getElementById('btn-accept');
|
||||
const btnCancel = document.getElementById('btn-cancel');
|
||||
const croppedInput = document.getElementById('croppedImage');
|
||||
|
||||
let cropper;
|
||||
|
||||
// When file is selected
|
||||
fileInput.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
// Hide upload label and preview, show cropper
|
||||
uploadLabel.style.display = 'none';
|
||||
previewBox.style.display = 'none';
|
||||
cropperBox.style.display = 'block';
|
||||
|
||||
cropperImg.src = event.target.result;
|
||||
|
||||
// Destroy existing cropper if any
|
||||
if (cropper) cropper.destroy();
|
||||
|
||||
// Initialize Cropper.js
|
||||
cropper = new Cropper(cropperImg, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 1,
|
||||
autoCropArea: 1
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
// Accept crop
|
||||
btnAccept.addEventListener('click', () => {
|
||||
const canvas = cropper.getCroppedCanvas({ width: 600, height: 600 });
|
||||
const dataUrl = canvas.toDataURL('image/jpeg', 0.9);
|
||||
|
||||
// Store cropped image
|
||||
croppedInput.value = dataUrl;
|
||||
|
||||
// Show preview
|
||||
previewImg.src = dataUrl;
|
||||
cropperBox.style.display = 'none';
|
||||
previewBox.style.display = 'block';
|
||||
|
||||
// Destroy cropper
|
||||
cropper.destroy();
|
||||
cropper = null;
|
||||
});
|
||||
|
||||
// Cancel crop
|
||||
btnCancel.addEventListener('click', () => {
|
||||
fileInput.value = '';
|
||||
cropperBox.style.display = 'none';
|
||||
uploadLabel.style.display = 'flex';
|
||||
if (cropper) {
|
||||
cropper.destroy();
|
||||
cropper = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Click preview to change photo
|
||||
previewBox.addEventListener('click', () => {
|
||||
fileInput.click();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script defer src="./assets/js/home.js"></script>
|
||||
<script defer src="https://unpkg.com/alpinejs@3.15.5/dist/cdn.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue