131 lines
4.2 KiB
JavaScript
131 lines
4.2 KiB
JavaScript
import { useContext, useState } from "react";
|
||
import { createHousehold, joinHousehold } from "../../api/households";
|
||
import { HouseholdContext } from "../../context/HouseholdContext";
|
||
import "../../styles/components/manage/CreateJoinHousehold.css";
|
||
|
||
export default function CreateJoinHousehold({ onClose }) {
|
||
const { refreshHouseholds } = useContext(HouseholdContext);
|
||
const [mode, setMode] = useState("create"); // "create" or "join"
|
||
const [householdName, setHouseholdName] = useState("");
|
||
const [inviteCode, setInviteCode] = useState("");
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState("");
|
||
|
||
const handleCreate = async (e) => {
|
||
e.preventDefault();
|
||
if (!householdName.trim()) return;
|
||
|
||
setLoading(true);
|
||
setError("");
|
||
|
||
try {
|
||
await createHousehold(householdName);
|
||
await refreshHouseholds();
|
||
onClose();
|
||
} catch (err) {
|
||
console.error("Failed to create household:", err);
|
||
setError(err.response?.data?.message || "Failed to create household");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
const handleJoin = async (e) => {
|
||
e.preventDefault();
|
||
if (!inviteCode.trim()) return;
|
||
|
||
setLoading(true);
|
||
setError("");
|
||
|
||
try {
|
||
await joinHousehold(inviteCode);
|
||
await refreshHouseholds();
|
||
onClose();
|
||
} catch (err) {
|
||
console.error("Failed to join household:", err);
|
||
setError(err.response?.data?.message || "Failed to join household");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="create-join-modal-overlay" onClick={onClose}>
|
||
<div className="create-join-modal" onClick={(e) => e.stopPropagation()}>
|
||
<div className="modal-header">
|
||
<h2>Household</h2>
|
||
<button className="close-btn" onClick={onClose}>×</button>
|
||
</div>
|
||
|
||
<div className="mode-tabs">
|
||
<button
|
||
className={`mode-tab ${mode === "create" ? "active" : ""}`}
|
||
onClick={() => setMode("create")}
|
||
>
|
||
Create New
|
||
</button>
|
||
<button
|
||
className={`mode-tab ${mode === "join" ? "active" : ""}`}
|
||
onClick={() => setMode("join")}
|
||
>
|
||
Join Existing
|
||
</button>
|
||
</div>
|
||
|
||
{error && <div className="error-message">{error}</div>}
|
||
|
||
{mode === "create" ? (
|
||
<form onSubmit={handleCreate} className="household-form">
|
||
<div className="form-group">
|
||
<label htmlFor="householdName">Household Name</label>
|
||
<input
|
||
id="householdName"
|
||
type="text"
|
||
value={householdName}
|
||
onChange={(e) => setHouseholdName(e.target.value)}
|
||
placeholder="e.g., Smith Family"
|
||
required
|
||
autoFocus
|
||
/>
|
||
</div>
|
||
<div className="form-actions">
|
||
<button type="button" onClick={onClose} className="btn-secondary">
|
||
Cancel
|
||
</button>
|
||
<button type="submit" className="btn-primary" disabled={loading}>
|
||
{loading ? "Creating..." : "Create Household"}
|
||
</button>
|
||
</div>
|
||
</form>
|
||
) : (
|
||
<form onSubmit={handleJoin} className="household-form">
|
||
<div className="form-group">
|
||
<label htmlFor="inviteCode">Invite Code</label>
|
||
<input
|
||
id="inviteCode"
|
||
type="text"
|
||
value={inviteCode}
|
||
onChange={(e) => setInviteCode(e.target.value)}
|
||
placeholder="Enter invite code"
|
||
required
|
||
autoFocus
|
||
/>
|
||
<p className="form-hint">
|
||
Ask the household admin for the invite code
|
||
</p>
|
||
</div>
|
||
<div className="form-actions">
|
||
<button type="button" onClick={onClose} className="btn-secondary">
|
||
Cancel
|
||
</button>
|
||
<button type="submit" className="btn-primary" disabled={loading}>
|
||
{loading ? "Joining..." : "Join Household"}
|
||
</button>
|
||
</div>
|
||
</form>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|