first commit
This commit is contained in:
169
src/pages/Coupons/CreateCoupon.jsx
Normal file
169
src/pages/Coupons/CreateCoupon.jsx
Normal file
@@ -0,0 +1,169 @@
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useCreateCouponMutation } from "../../features/coupons/couponAPI";
|
||||
|
||||
const CreateCoupon = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
// RTK Query mutation
|
||||
const [createCoupon, { isLoading }] = useCreateCouponMutation();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
code: "",
|
||||
description: "",
|
||||
type: "PERCENTAGE",
|
||||
value: "",
|
||||
minOrderAmount: "",
|
||||
maxUses: "",
|
||||
validFrom: "",
|
||||
validUntil: "",
|
||||
});
|
||||
|
||||
const handleChange = (e) => {
|
||||
setForm({ ...form, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
await createCoupon({
|
||||
...form,
|
||||
value: Number(form.value),
|
||||
minOrderAmount: Number(form.minOrderAmount || 0),
|
||||
maxUses: Number(form.maxUses || 0),
|
||||
}).unwrap();
|
||||
|
||||
// redirect after success
|
||||
navigate("/admin/coupons");
|
||||
} catch (error) {
|
||||
console.error("Failed to create coupon:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex justify-center mt-5 px-4">
|
||||
<div className="w-full max-w-3xl space-y-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-xl font-semibold text-gray-600">
|
||||
Create Coupon
|
||||
</h1>
|
||||
<button
|
||||
onClick={() => navigate("/admin/coupons")}
|
||||
className="text-sm text-gray-500 hover:text-gray-700"
|
||||
>
|
||||
← Back
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Form Card */}
|
||||
<div className="bg-white rounded-2xl border border-[#B9B9B9] p-6 shadow-sm">
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
{/* Coupon Code */}
|
||||
<input
|
||||
name="code"
|
||||
placeholder="Coupon Code"
|
||||
value={form.code}
|
||||
className="w-full border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
|
||||
{/* Description */}
|
||||
<input
|
||||
name="description"
|
||||
placeholder="Description"
|
||||
value={form.description}
|
||||
className="w-full border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
{/* Type & Value */}
|
||||
<div className="flex gap-4">
|
||||
<select
|
||||
name="type"
|
||||
value={form.type}
|
||||
className="w-1/2 border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
>
|
||||
<option value="PERCENTAGE">Percentage</option>
|
||||
<option value="FLAT">Flat</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
name="value"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
value={form.value}
|
||||
className="w-1/2 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Min Order & Max Uses */}
|
||||
<div className="flex gap-4">
|
||||
<input
|
||||
name="minOrderAmount"
|
||||
type="number"
|
||||
placeholder="Min Order Amount"
|
||||
value={form.minOrderAmount}
|
||||
className="w-1/2 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
<input
|
||||
name="maxUses"
|
||||
type="number"
|
||||
placeholder="Max Uses"
|
||||
value={form.maxUses}
|
||||
className="w-1/2 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Valid Dates */}
|
||||
<div className="flex gap-4">
|
||||
<input
|
||||
name="validFrom"
|
||||
type="date"
|
||||
value={form.validFrom}
|
||||
className="w-1/2 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<input
|
||||
name="validUntil"
|
||||
type="date"
|
||||
value={form.validUntil}
|
||||
className="w-1/2 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex justify-end gap-3 pt-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/admin/coupons")}
|
||||
className="px-4 py-2 rounded-lg border hover:bg-gray-50"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50"
|
||||
>
|
||||
{isLoading ? "Creating..." : "Create Coupon"}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateCoupon;
|
||||
Reference in New Issue
Block a user