Skip to content

Commit

Permalink
add validation,modify pdf (#123)
Browse files Browse the repository at this point in the history
Co-authored-by: IT22171856 <142132191+IT22171856@users.noreply.github.com>
  • Loading branch information
GayashanHansaja and GayashanHansaja authored Oct 14, 2024
1 parent d647bf1 commit 24e59a2
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 55 deletions.
108 changes: 72 additions & 36 deletions frontend/src/Pages/Admin/AaddCoupons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,88 @@ import Swal from 'sweetalert2'
import Sidebar from '../../Components/Admin/AsideBar'

const AddCoupon = () => {
const navigate = useNavigate()
const navigate = useNavigate();
const [formData, setFormData] = useState({
couponCode: '',
discount: '',
expiryDate: '',
})
const [loading, setLoading] = useState(false)
});
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState({
couponCode: '',
discount: '',
expiryDate: '',
})
});

// Handle input change with validation
const handleChange = (e) => {
const { name, value } = e.target
setFormData({ ...formData, [name]: value })
const { name, value } = e.target;
let error = '';

// Simple validation for discount (should be a number)
// Coupon Code validation: Ensure it's not empty
if (name === 'couponCode' && value === '') {
error = 'Coupon code cannot be empty';
}

// Discount validation: Must be a number and <= 100
if (name === 'discount') {
const discountRegex = /^\d+$/ // Accept only digits
setErrors({
...errors,
discount: !discountRegex.test(value)
? 'Discount must be a number'
: '',
})
const discountValue = parseInt(value, 10);
if (isNaN(discountValue) || discountValue < 0) {
error = 'Discount must be a positive number';
} else if (discountValue > 100) {
error = 'Discount cannot be more than 100';
}
}
// Expiry date validation: Must be today or a future date
if (name === 'expiryDate') {
const minDate = new Date('2024-10-15')
const maxDate = new Date('2030-01-01')
const selectedDate = new Date(value)
if (selectedDate < minDate || selectedDate > maxDate) {
error = 'Birthday must be between today and upcoming'
}
}
}

// Update form data and errors
setFormData({ ...formData, [name]: value });
setErrors({ ...errors, [name]: error });
};

// Handle form submission
const handleSubmit = async (e) => {
e.preventDefault()
if (errors.discount) {
Swal.fire('Validation Error', 'Please fix the errors', 'error')
return
e.preventDefault();
// Check if any validation errors exist
if (Object.values(errors).some((err) => err)) {
Swal.fire('Validation Error', 'Please fix the errors', 'error');
return;
}

try {
setLoading(true)
setLoading(true);

await axios.post('/coupon', formData, {
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`,
},
})
});

Swal.fire('Success', 'Coupon created successfully', 'success')
navigate('/coupons') // Redirect to coupons page after creation
Swal.fire('Success', 'Coupon created successfully', 'success');
navigate('/coupons');
} catch (err) {
console.error('Error creating coupon:', err)
console.error('Error creating coupon:', err);
Swal.fire(
'Error',
'Error creating coupon, please try again',
'error'
)
);
} finally {
setLoading(false)
setLoading(false);
}
}
};

const handleCancel = () => {
navigate('/coupons') // Navigate back to coupons page
}
navigate('/coupons');
};

return (
<div className="flex min-h-screen bg-gray-50">
Expand Down Expand Up @@ -100,6 +120,11 @@ const AddCoupon = () => {
onChange={handleChange}
required
/>
{errors.couponCode && (
<p className="text-red-500 text-xs">
{errors.couponCode}
</p>
)}
</div>
<div>
<label className="block text-gray-700">
Expand All @@ -111,6 +136,11 @@ const AddCoupon = () => {
className="w-full mt-1 p-2 border border-gray-300 rounded"
value={formData.discount}
onChange={handleChange}
onBlur={() => {
if (parseInt(formData.discount, 10) > 100) {
setFormData({ ...formData, discount: '100' });
}
}}
required
/>
{errors.discount && (
Expand All @@ -130,31 +160,37 @@ const AddCoupon = () => {
value={formData.expiryDate}
onChange={handleChange}
required
min="2024-10-15"
max="2030-10-15"
/>
{errors.expiryDate && (
<p className="text-red-500 text-xs">
{errors.expiryDate}
</p>
)}
</div>
</div>
</div>

<div className="flex gap-x-5 mt-4">
<div className="flex justify-end space-x-4 mt-6">
<button
type="submit"
className="bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600"
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
disabled={loading}
>
{loading ? 'Creating...' : 'Create Coupon'}
</button>
<button
type="button"
onClick={handleCancel}
className="bg-red-500 text-white py-2 px-4 rounded hover:bg-red-600"
className="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600"
>
Cancel
</button>
</div>
</form>
</div>
</div>
)
}
);
};

export default AddCoupon
export default AddCoupon;
68 changes: 49 additions & 19 deletions frontend/src/Pages/Admin/Astaff.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Swal from 'sweetalert2'
import jsPDF from 'jspdf'
import 'jspdf-autotable'
import logo from '../../assets/logo.png'
import image from '../../assets/logo/image.png'
import { FaDownload } from 'react-icons/fa'
import Header from '../../Components/Admin/Aheader.jsx'

Check failure on line 27 in frontend/src/Pages/Admin/Astaff.jsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

frontend/src/Pages/Admin/Astaff.jsx#L27

[no-unused-vars] 'Header' is defined but never used.

Expand Down Expand Up @@ -108,18 +109,31 @@ const Staff = () => {
navigate(`/updatestaff/${memberId}`)
}

// PDF Generation
const generatePDF = () => {
const doc = new jsPDF()
const img = new Image()
img.src = logo
const doc = new jsPDF();
const img = new Image();
const img1 = new Image();
img.src = logo;
img1.src = image;
// Add logo
doc.addImage(img, 'PNG', 20, 35, 30, 5) // Adjust the X, Y, width, and height as needed // Adjust x, y, width, height as needed
doc.addImage(img, 'PNG', 20, 20, 35, 10); // Adjust x, y, width, height as needed
// Get the width of the PDF page
const pdfWidth = doc.internal.pageSize.getWidth();
const imgWidth = 60; // Width of the image
const imgHeight = 25; // Height of the image

// Adjustments for moving the image higher and left
const xPosition = pdfWidth - imgWidth - 10; // Move left by 10 units
const yPosition = 20; // Move up on the Y-axis (reduce from 35 to 20)

// Position the image
doc.addImage(img1, 'PNG', xPosition, yPosition, imgWidth, imgHeight);


// Add title below the logo
doc.setFontSize(15)
doc.text('Staff List', 105, 40, null, null, 'center') // Centered below logo

doc.setFontSize(15);
doc.text('Staff List', 105, 40, null, null, 'center'); // Centered below logo
// Prepare the table data
const tableColumn = [
'Id',
Expand All @@ -129,9 +143,9 @@ const Staff = () => {
'Birth Day',
'Address',
'Role',
]
const tableRows = []

];
const tableRows = [];
filteredStaff.forEach((member, index) => {
const memberData = [
index + 1,
Expand All @@ -141,10 +155,11 @@ const Staff = () => {
member.birthday.split('T')[0],
`${member.Address.home} ${member.Address.street} ${member.Address.city}`,
member.role,
]
tableRows.push(memberData)
})

];
tableRows.push(memberData);
});


// Add table to PDF
doc.autoTable({
head: [tableColumn],
Expand All @@ -153,10 +168,25 @@ const Staff = () => {
styles: {
fontSize: 9, // Adjust this value to make the table content smaller
},
})

doc.save('staff-list.pdf')
}
});

// Get the final Y position after the table
const finalY = doc.lastAutoTable.finalY;

// Add current date and time below the table, aligned to the left
const currentDate = new Date();
const dateString = currentDate.toLocaleDateString(); // Format: MM/DD/YYYY or local format
const timeString = currentDate.toLocaleTimeString(); // Format: HH:MM:SS AM/PM or local format

doc.setFontSize(8); // Smaller font for date and time
doc.text(`Generated on: ${dateString} at ${timeString}`, 20, finalY + 10, null, null, 'left'); // Left side of the document

// Save the PDF
doc.save('staff-list.pdf');
};




if (loading) {
return (
Expand Down
Binary file added frontend/src/assets/logo/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 24e59a2

Please sign in to comment.