costco-grocery-list/frontend/src/components/manage/CreateJoinHousehold.jsx

131 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
}