Mapping made_by to displayname
This commit is contained in:
parent
53ca792988
commit
fa5ba578bb
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -54,10 +54,12 @@ def list_recipes_db() -> List[Dict[str, Any]]:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT id, name, meal_type, time_minutes,
|
||||
tags, ingredients, steps, image, made_by, user_id
|
||||
FROM recipes
|
||||
ORDER BY id
|
||||
SELECT r.id, r.name, r.meal_type, r.time_minutes,
|
||||
r.tags, r.ingredients, r.steps, r.image, r.made_by, r.user_id,
|
||||
u.display_name as owner_display_name
|
||||
FROM recipes r
|
||||
LEFT JOIN users u ON r.user_id = u.id
|
||||
ORDER BY r.id
|
||||
"""
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
@ -163,19 +165,21 @@ def get_recipes_by_filters_db(
|
||||
conn = get_conn()
|
||||
try:
|
||||
query = """
|
||||
SELECT id, name, meal_type, time_minutes,
|
||||
tags, ingredients, steps, image, made_by, user_id
|
||||
FROM recipes
|
||||
SELECT r.id, r.name, r.meal_type, r.time_minutes,
|
||||
r.tags, r.ingredients, r.steps, r.image, r.made_by, r.user_id,
|
||||
u.display_name as owner_display_name
|
||||
FROM recipes r
|
||||
LEFT JOIN users u ON r.user_id = u.id
|
||||
WHERE 1=1
|
||||
"""
|
||||
params: List = []
|
||||
|
||||
if meal_type:
|
||||
query += " AND meal_type = %s"
|
||||
query += " AND r.meal_type = %s"
|
||||
params.append(meal_type.lower())
|
||||
|
||||
if max_time:
|
||||
query += " AND time_minutes <= %s"
|
||||
query += " AND r.time_minutes <= %s"
|
||||
params.append(max_time)
|
||||
|
||||
with conn.cursor() as cur:
|
||||
|
||||
@ -51,6 +51,7 @@ class RecipeCreate(RecipeBase):
|
||||
class Recipe(RecipeBase):
|
||||
id: int
|
||||
user_id: Optional[int] = None # Recipe owner ID
|
||||
owner_display_name: Optional[str] = None # Owner's display name for filtering
|
||||
|
||||
|
||||
class RecipeUpdate(RecipeBase):
|
||||
@ -132,6 +133,7 @@ def list_recipes():
|
||||
steps=r["steps"] or [],
|
||||
image=r.get("image"),
|
||||
user_id=r.get("user_id"),
|
||||
owner_display_name=r.get("owner_display_name"),
|
||||
)
|
||||
for r in rows
|
||||
]
|
||||
@ -157,6 +159,7 @@ def create_recipe(recipe_in: RecipeCreate, current_user: dict = Depends(get_curr
|
||||
steps=row["steps"] or [],
|
||||
image=row.get("image"),
|
||||
user_id=row.get("user_id"),
|
||||
owner_display_name=current_user.get("display_name"),
|
||||
)
|
||||
|
||||
@app.put("/recipes/{recipe_id}", response_model=Recipe)
|
||||
@ -192,6 +195,7 @@ def update_recipe(recipe_id: int, recipe_in: RecipeUpdate, current_user: dict =
|
||||
steps=row["steps"] or [],
|
||||
image=row.get("image"),
|
||||
user_id=row.get("user_id"),
|
||||
owner_display_name=current_user.get("display_name"),
|
||||
)
|
||||
|
||||
|
||||
@ -239,6 +243,7 @@ def random_recipe(
|
||||
steps=r["steps"] or [],
|
||||
image=r.get("image"),
|
||||
user_id=r.get("user_id"),
|
||||
owner_display_name=r.get("owner_display_name"),
|
||||
)
|
||||
for r in rows
|
||||
]
|
||||
@ -288,6 +293,17 @@ def register(user: UserRegister):
|
||||
detail="האימייל כבר רשום במערכת"
|
||||
)
|
||||
|
||||
# Check if display_name already exists
|
||||
print(f"[REGISTER] Checking if display_name exists...")
|
||||
from user_db_utils import get_user_by_display_name
|
||||
existing_display_name = get_user_by_display_name(user.display_name)
|
||||
if existing_display_name:
|
||||
print(f"[REGISTER] Display name already exists")
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="שם התצוגה כבר קיים במערכת"
|
||||
)
|
||||
|
||||
# Hash password and create user
|
||||
print(f"[REGISTER] Hashing password...")
|
||||
password_hash = hash_password(user.password)
|
||||
|
||||
@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
password_hash TEXT NOT NULL,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
display_name TEXT NOT NULL,
|
||||
display_name TEXT UNIQUE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@ -84,3 +84,19 @@ def get_user_by_id(user_id: int):
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_user_by_display_name(display_name: str):
|
||||
"""Get user by display name"""
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
try:
|
||||
cur.execute(
|
||||
"SELECT id, username, email, display_name, created_at FROM users WHERE display_name = %s",
|
||||
(display_name,)
|
||||
)
|
||||
user = cur.fetchone()
|
||||
return dict(user) if user else None
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
@ -27,7 +27,7 @@ function App() {
|
||||
const [filterMealType, setFilterMealType] = useState("");
|
||||
const [filterMaxTime, setFilterMaxTime] = useState("");
|
||||
const [filterTags, setFilterTags] = useState([]);
|
||||
const [filterMadeBy, setFilterMadeBy] = useState("");
|
||||
const [filterOwner, setFilterOwner] = useState("");
|
||||
|
||||
// Random recipe filters
|
||||
const [mealTypeFilter, setMealTypeFilter] = useState("");
|
||||
@ -126,8 +126,8 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by made_by
|
||||
if (filterMadeBy && (!recipe.made_by || recipe.made_by !== filterMadeBy)) {
|
||||
// Filter by made_by (username)
|
||||
if (filterOwner && (!recipe.made_by || recipe.made_by !== filterOwner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -343,8 +343,8 @@ function App() {
|
||||
onMaxTimeChange={setFilterMaxTime}
|
||||
filterTags={filterTags}
|
||||
onTagsChange={setFilterTags}
|
||||
filterMadeBy={filterMadeBy}
|
||||
onMadeByChange={setFilterMadeBy}
|
||||
filterOwner={filterOwner}
|
||||
onOwnerChange={setFilterOwner}
|
||||
/>
|
||||
</section>
|
||||
|
||||
|
||||
@ -35,8 +35,8 @@ function RecipeDetails({ recipe, onEditClick, onDeleteClick, onShowDeleteModal,
|
||||
<p className="recipe-subtitle">
|
||||
{translateMealType(recipe.meal_type)} · {recipe.time_minutes} דקות הכנה
|
||||
</p>
|
||||
{recipe.made_by && (
|
||||
<h4 className="recipe-made-by">המתכון של: {recipe.made_by}</h4>
|
||||
{(recipe.owner_display_name || recipe.made_by) && (
|
||||
<h4 className="recipe-made-by">המתכון של: {recipe.owner_display_name || recipe.made_by}</h4>
|
||||
)}
|
||||
</div>
|
||||
<div className="pill-row">
|
||||
|
||||
@ -14,8 +14,8 @@ function RecipeSearchList({
|
||||
onMaxTimeChange,
|
||||
filterTags,
|
||||
onTagsChange,
|
||||
filterMadeBy,
|
||||
onMadeByChange,
|
||||
filterOwner,
|
||||
onOwnerChange,
|
||||
}) {
|
||||
const [expandFilters, setExpandFilters] = useState(false);
|
||||
|
||||
@ -27,8 +27,14 @@ function RecipeSearchList({
|
||||
// Extract unique meal types from ALL recipes (not filtered)
|
||||
const mealTypes = Array.from(new Set(allRecipes.map((r) => r.meal_type))).sort();
|
||||
|
||||
// Extract unique made_by from ALL recipes (not filtered)
|
||||
const allMadeBy = Array.from(new Set(allRecipes.map((r) => r.made_by).filter(Boolean))).sort();
|
||||
// Extract unique made_by (username) from ALL recipes and map to display names
|
||||
const madeByMap = new Map();
|
||||
allRecipes.forEach((r) => {
|
||||
if (r.made_by && r.owner_display_name) {
|
||||
madeByMap.set(r.made_by, r.owner_display_name);
|
||||
}
|
||||
});
|
||||
const allMadeBy = Array.from(madeByMap.keys()).sort();
|
||||
|
||||
// Extract max time for slider from ALL recipes (not filtered) - add 10 to make it comfortable to select max time recipes
|
||||
const maxTimeInRecipes = Math.max(...allRecipes.map((r) => r.time_minutes), 0);
|
||||
@ -47,10 +53,10 @@ function RecipeSearchList({
|
||||
onMealTypeChange("");
|
||||
onMaxTimeChange("");
|
||||
onTagsChange([]);
|
||||
onMadeByChange("");
|
||||
onOwnerChange("");
|
||||
};
|
||||
|
||||
const hasActiveFilters = searchQuery || filterMealType || filterMaxTime || filterTags.length > 0 || filterMadeBy;
|
||||
const hasActiveFilters = searchQuery || filterMealType || filterMaxTime || filterTags.length > 0 || filterOwner;
|
||||
|
||||
return (
|
||||
<section className="panel secondary recipe-search-list">
|
||||
@ -165,18 +171,18 @@ function RecipeSearchList({
|
||||
<label className="filter-label">המתכונים של:</label>
|
||||
<div className="filter-options">
|
||||
<button
|
||||
className={`filter-btn ${filterMadeBy === "" ? "active" : ""}`}
|
||||
onClick={() => onMadeByChange("")}
|
||||
className={`filter-btn ${filterOwner === "" ? "active" : ""}`}
|
||||
onClick={() => onOwnerChange("")}
|
||||
>
|
||||
הכל
|
||||
</button>
|
||||
{allMadeBy.map((person) => (
|
||||
{allMadeBy.map((madeBy) => (
|
||||
<button
|
||||
key={person}
|
||||
className={`filter-btn ${filterMadeBy === person ? "active" : ""}`}
|
||||
onClick={() => onMadeByChange(person)}
|
||||
key={madeBy}
|
||||
className={`filter-btn ${filterOwner === madeBy ? "active" : ""}`}
|
||||
onClick={() => onOwnerChange(madeBy)}
|
||||
>
|
||||
{person}
|
||||
{madeByMap.get(madeBy) || madeBy}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user