File size: 3,754 Bytes
135b02e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | // frontend/src/components/admin/MembershipInviteForm.jsx
import React, { useState } from "react";
import { Send, X } from "lucide-react";
export default function MembershipInviteForm({
plans,
onSend,
onCancel,
isLoading,
}) {
const [email, setEmail] = useState("parent@email.com");
const [selectedPlanId, setSelectedPlanId] = useState("");
const [classDetails, setClassDetails] = useState("");
const selectedPlan = plans.find((p) => p.id === parseInt(selectedPlanId));
const handleSubmit = (e) => {
e.preventDefault();
if (!email.trim() || !selectedPlanId) {
return;
}
onSend({
email: email.trim(),
plan_id: parseInt(selectedPlanId),
class_details: classDetails.trim(),
invited_by: "admin",
});
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-stone-700 mb-1.5">
Email Address
</label>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full rounded-lg border border-stone-200 px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500"
placeholder="parent@email.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-stone-700 mb-1.5">
Membership Plan
</label>
<select
required
value={selectedPlanId}
onChange={(e) => setSelectedPlanId(e.target.value)}
className="w-full rounded-lg border border-stone-200 px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500"
>
<option value="">Select a plan...</option>
{plans
.filter((p) => p.is_active)
.map((plan) => (
<option key={plan.id} value={plan.id}>
{plan.name} - ${plan.price}/{plan.billing_period} (Up to{" "}
{plan.max_students || 1} student{plan.max_students !== 1 ? "s" : ""})
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-stone-700 mb-1.5">
Class Information (shown to member)
</label>
<textarea
value={classDetails}
onChange={(e) => setClassDetails(e.target.value)}
rows={4}
className="w-full rounded-lg border border-stone-200 px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500"
placeholder="e.g., Beginner Karate - Mon & Wed 4:00 PM, Advanced Karate - Fri 5:00 PM"
/>
<p className="text-xs text-stone-500 mt-1">
Describe the classes included so the member knows what they're signing
up for
</p>
</div>
<div className="flex items-center justify-end gap-2 pt-2">
<button
type="button"
onClick={onCancel}
disabled={isLoading}
className="inline-flex items-center gap-2 rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium text-stone-700 hover:bg-stone-50 disabled:opacity-50"
>
<X className="w-4 h-4" />
Cancel
</button>
<button
type="submit"
disabled={isLoading || !email.trim() || !selectedPlanId}
className="inline-flex items-center gap-2 rounded-lg bg-red-600 hover:bg-red-700 text-white text-sm font-medium px-4 py-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
<Send className="w-4 h-4" />
{isLoading ? "Sending..." : "Send Invite"}
</button>
</div>
</form>
);
}
|