section improvements
This commit is contained in:
24
app.py
24
app.py
@@ -203,7 +203,7 @@ def home():
|
|||||||
query = query.filter(Plant.care_difficulty_id == care_difficulty_id)
|
query = query.filter(Plant.care_difficulty_id == care_difficulty_id)
|
||||||
if growth_rate_id:
|
if growth_rate_id:
|
||||||
query = query.filter(Plant.growth_rate_id == growth_rate_id)
|
query = query.filter(Plant.growth_rate_id == growth_rate_id)
|
||||||
if section_id and hasattr(Plant, 'section_id'):
|
if section_id:
|
||||||
query = query.filter(Plant.section_id == section_id)
|
query = query.filter(Plant.section_id == section_id)
|
||||||
plants = query.order_by(Plant.date_added.desc()).all()
|
plants = query.order_by(Plant.date_added.desc()).all()
|
||||||
|
|
||||||
@@ -221,6 +221,7 @@ def home():
|
|||||||
product_names.append(products_dict[int(pid)])
|
product_names.append(products_dict[int(pid)])
|
||||||
climate_info = climates_dict.get(plant.climate_id, {'name': '', 'icon': None, 'description': ''})
|
climate_info = climates_dict.get(plant.climate_id, {'name': '', 'icon': None, 'description': ''})
|
||||||
environment_info = environments_dict.get(plant.environment_id, {'name': '', 'icon': None, 'description': ''})
|
environment_info = environments_dict.get(plant.environment_id, {'name': '', 'icon': None, 'description': ''})
|
||||||
|
|
||||||
display_plants.append({
|
display_plants.append({
|
||||||
'id': plant.id,
|
'id': plant.id,
|
||||||
'name': plant.name,
|
'name': plant.name,
|
||||||
@@ -249,17 +250,19 @@ def home():
|
|||||||
'growth_rate': plant.growth_rate.name if plant.growth_rate else '',
|
'growth_rate': plant.growth_rate.name if plant.growth_rate else '',
|
||||||
'growth_rate_icon': plant.growth_rate.icon if plant.growth_rate and plant.growth_rate.icon else None,
|
'growth_rate_icon': plant.growth_rate.icon if plant.growth_rate and plant.growth_rate.icon else None,
|
||||||
'growth_rate_description': plant.growth_rate.description if plant.growth_rate else '',
|
'growth_rate_description': plant.growth_rate.description if plant.growth_rate else '',
|
||||||
|
'section': plant.section
|
||||||
})
|
})
|
||||||
|
|
||||||
return render_template('home.html',
|
return render_template('home.html',
|
||||||
plants=display_plants,
|
plants=display_plants,
|
||||||
climates=Climate.query.all(),
|
climates=Climate.query.all(),
|
||||||
environments=Environment.query.all(),
|
environments=Environment.query.all(),
|
||||||
lights=Light.query.order_by(Light.name).all(),
|
lights=Light.query.all(),
|
||||||
toxicities=Toxicity.query.order_by(Toxicity.name).all(),
|
toxicities=Toxicity.query.all(),
|
||||||
sizes=Size.query.order_by(Size.name).all(),
|
sizes=Size.query.all(),
|
||||||
difficulties=CareDifficulty.query.order_by(CareDifficulty.name).all(),
|
difficulties=CareDifficulty.query.all(),
|
||||||
growth_rates=GrowthRate.query.order_by(GrowthRate.name).all(),
|
growth_rates=GrowthRate.query.all(),
|
||||||
|
sections=Section.query.all(),
|
||||||
search=search,
|
search=search,
|
||||||
selected_climate=climate_id,
|
selected_climate=climate_id,
|
||||||
selected_environment=environment_id,
|
selected_environment=environment_id,
|
||||||
@@ -267,8 +270,8 @@ def home():
|
|||||||
selected_toxicity=toxicity_id,
|
selected_toxicity=toxicity_id,
|
||||||
selected_size=size_id,
|
selected_size=size_id,
|
||||||
selected_care_difficulty=care_difficulty_id,
|
selected_care_difficulty=care_difficulty_id,
|
||||||
selected_growth_rate=growth_rate_id
|
selected_growth_rate=growth_rate_id,
|
||||||
)
|
selected_section=section_id)
|
||||||
|
|
||||||
@app.route('/login', methods=['GET', 'POST'])
|
@app.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
@@ -624,6 +627,7 @@ def edit_plant(plant_id):
|
|||||||
sizes = Size.query.order_by(Size.name).all()
|
sizes = Size.query.order_by(Size.name).all()
|
||||||
difficulties = CareDifficulty.query.order_by(CareDifficulty.name).all()
|
difficulties = CareDifficulty.query.order_by(CareDifficulty.name).all()
|
||||||
growth_rates = GrowthRate.query.order_by(GrowthRate.name).all()
|
growth_rates = GrowthRate.query.order_by(GrowthRate.name).all()
|
||||||
|
sections = Section.query.order_by(Section.name).all()
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
plant.name = request.form['name']
|
plant.name = request.form['name']
|
||||||
@@ -634,6 +638,7 @@ def edit_plant(plant_id):
|
|||||||
plant.size_id = request.form.get('size_id')
|
plant.size_id = request.form.get('size_id')
|
||||||
plant.care_difficulty_id = request.form.get('care_difficulty_id')
|
plant.care_difficulty_id = request.form.get('care_difficulty_id')
|
||||||
plant.growth_rate_id = request.form.get('growth_rate_id')
|
plant.growth_rate_id = request.form.get('growth_rate_id')
|
||||||
|
plant.section_id = request.form.get('section_id')
|
||||||
plant.products = ','.join(request.form.getlist('product_ids'))
|
plant.products = ','.join(request.form.getlist('product_ids'))
|
||||||
plant.description = request.form['description']
|
plant.description = request.form['description']
|
||||||
plant.care_guide = request.form.get('care_guide')
|
plant.care_guide = request.form.get('care_guide')
|
||||||
@@ -661,7 +666,8 @@ def edit_plant(plant_id):
|
|||||||
toxicities=toxicities,
|
toxicities=toxicities,
|
||||||
sizes=sizes,
|
sizes=sizes,
|
||||||
difficulties=difficulties,
|
difficulties=difficulties,
|
||||||
growth_rates=growth_rates)
|
growth_rates=growth_rates,
|
||||||
|
sections=sections)
|
||||||
|
|
||||||
@app.route('/plant/delete/<int:plant_id>', methods=['POST'])
|
@app.route('/plant/delete/<int:plant_id>', methods=['POST'])
|
||||||
def delete_plant(plant_id):
|
def delete_plant(plant_id):
|
||||||
|
|||||||
@@ -21,6 +21,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label for="section_id" class="block text-sm font-medium text-gray-700">Section</label>
|
||||||
|
<select name="section_id" id="section_id" required
|
||||||
|
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
|
||||||
|
<option value="">Select a section</option>
|
||||||
|
{% for section in sections %}
|
||||||
|
<option value="{{ section.id }}" {% if plant.section_id == section.id %}selected{% endif %}>{{ section.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="climate_id" class="block text-sm font-medium text-gray-700">Climate</label>
|
<label for="climate_id" class="block text-sm font-medium text-gray-700">Climate</label>
|
||||||
<select name="climate_id" id="climate_id" required
|
<select name="climate_id" id="climate_id" required
|
||||||
|
|||||||
@@ -52,6 +52,12 @@
|
|||||||
<option value="{{ rate.id }}" {% if selected_growth_rate == rate.id|string %}selected{% endif %}>{{ rate.name }}</option>
|
<option value="{{ rate.id }}" {% if selected_growth_rate == rate.id|string %}selected{% endif %}>{{ rate.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
<select id="section" name="section" class="rounded-lg border border-gray-300 px-3 py-1 text-sm focus:border-[#6b8f71] focus:ring-[#6b8f71]">
|
||||||
|
<option value="">All Sections</option>
|
||||||
|
{% for section in sections %}
|
||||||
|
<option value="{{ section.id }}" {% if selected_section == section.id|string %}selected{% endif %}>{{ section.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
<a href="{{ url_for('home') }}" class="btn-secondary px-4 py-1 text-sm font-semibold ml-2 sm:ml-0">Clear</a>
|
<a href="{{ url_for('home') }}" class="btn-secondary px-4 py-1 text-sm font-semibold ml-2 sm:ml-0">Clear</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -67,7 +73,7 @@
|
|||||||
}
|
}
|
||||||
const form = document.getElementById('plant-filter-form');
|
const form = document.getElementById('plant-filter-form');
|
||||||
const searchInput = document.getElementById('search');
|
const searchInput = document.getElementById('search');
|
||||||
const selects = [document.getElementById('climate'), document.getElementById('environment'), document.getElementById('light'), document.getElementById('toxicity'), document.getElementById('size'), document.getElementById('care_difficulty'), document.getElementById('growth_rate')];
|
const selects = [document.getElementById('climate'), document.getElementById('environment'), document.getElementById('light'), document.getElementById('toxicity'), document.getElementById('size'), document.getElementById('care_difficulty'), document.getElementById('growth_rate'), document.getElementById('section')];
|
||||||
|
|
||||||
// Auto-submit on select change
|
// Auto-submit on select change
|
||||||
selects.forEach(sel => sel.addEventListener('change', () => form.submit()));
|
selects.forEach(sel => sel.addEventListener('change', () => form.submit()));
|
||||||
@@ -103,7 +109,17 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="w-full flex flex-col gap-2">
|
<div class="w-full flex flex-col gap-2">
|
||||||
<h2 class="text-2xl font-bold mb-1 text-[#4e6b50] group-hover:text-[#3e5637] transition">{{ plant.name }}</h2>
|
<h2 class="text-2xl font-bold mb-1 text-[#4e6b50] group-hover:text-[#3e5637] transition">{{ plant.name }}</h2>
|
||||||
|
{% if plant.section %}
|
||||||
|
<div class="text-sm text-[#6b8f71] mb-2">
|
||||||
|
<i class="fas fa-layer-group mr-1"></i>Section: {{ plant.section.name }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="flex flex-wrap gap-2 mb-1">
|
<div class="flex flex-wrap gap-2 mb-1">
|
||||||
|
<!-- Debug output -->
|
||||||
|
<div class="hidden">
|
||||||
|
Debug - Climate: {{ plant.climate }}
|
||||||
|
Debug - Environment: {{ plant.environment }}
|
||||||
|
</div>
|
||||||
<span class="tag-tooltip inline-flex items-center px-2 py-0.5 rounded text-[#3e5637] text-xs font-semibold" style="background-color: #d0e7d2;" data-type="climate">
|
<span class="tag-tooltip inline-flex items-center px-2 py-0.5 rounded text-[#3e5637] text-xs font-semibold" style="background-color: #d0e7d2;" data-type="climate">
|
||||||
{% if plant.climate_icon %}
|
{% if plant.climate_icon %}
|
||||||
<img src="{{ url_for('static', filename='icons/' ~ plant.climate_icon) }}" alt="Climate icon" class="w-4 h-4 mr-1 inline-block align-middle" />
|
<img src="{{ url_for('static', filename='icons/' ~ plant.climate_icon) }}" alt="Climate icon" class="w-4 h-4 mr-1 inline-block align-middle" />
|
||||||
|
|||||||
@@ -126,8 +126,6 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="border-b">
|
<tr class="border-b">
|
||||||
<th class="py-2 px-3">Name</th>
|
<th class="py-2 px-3">Name</th>
|
||||||
<th class="py-2 px-3">Climate</th>
|
|
||||||
<th class="py-2 px-3">Environment</th>
|
|
||||||
<th class="py-2 px-3">Added</th>
|
<th class="py-2 px-3">Added</th>
|
||||||
<th class="py-2 px-3">Actions</th>
|
<th class="py-2 px-3">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -136,8 +134,6 @@
|
|||||||
{% for plant in plants %}
|
{% for plant in plants %}
|
||||||
<tr class="border-b hover:bg-[#f5f7f2]">
|
<tr class="border-b hover:bg-[#f5f7f2]">
|
||||||
<td class="py-2 px-3 font-semibold">{{ plant.name }}</td>
|
<td class="py-2 px-3 font-semibold">{{ plant.name }}</td>
|
||||||
<td class="py-2 px-3">{{ climates[plant.climate_id] if plant.climate_id in climates else '' }}</td>
|
|
||||||
<td class="py-2 px-3">{{ environments[plant.environment_id] if plant.environment_id in environments else '' }}</td>
|
|
||||||
<td class="py-2 px-3"><span class="local-date" data-date="{{ plant.date_added.isoformat() }}"></span></td>
|
<td class="py-2 px-3"><span class="local-date" data-date="{{ plant.date_added.isoformat() }}"></span></td>
|
||||||
<td class="py-2 px-3">
|
<td class="py-2 px-3">
|
||||||
<a href="{{ url_for('edit_plant', plant_id=plant.id) }}" class="btn-edit">Edit</a>
|
<a href="{{ url_for('edit_plant', plant_id=plant.id) }}" class="btn-edit">Edit</a>
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="md:w-1/2 flex flex-col gap-4">
|
<div class="md:w-1/2 flex flex-col gap-4">
|
||||||
<h1 class="text-4xl font-bold text-[#4e6b50] mb-2">{{ plant.name }}</h1>
|
<h1 class="text-4xl font-bold text-[#4e6b50] mb-2">{{ plant.name }}</h1>
|
||||||
|
{% if plant.section %}
|
||||||
|
<div class="text-sm text-[#6b8f71] mb-2">
|
||||||
|
<i class="fas fa-layer-group mr-1"></i>Section: {{ plant.section.name }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="flex flex-wrap gap-2 mb-2">
|
<div class="flex flex-wrap gap-2 mb-2">
|
||||||
{% if plant.climate %}
|
{% if plant.climate %}
|
||||||
<span class="tag-tooltip inline-flex items-center px-2 py-0.5 rounded text-[#3e5637] text-xs font-semibold cursor-pointer transition-colors duration-200" style="background-color: #d0e7d2;" data-type="climate">
|
<span class="tag-tooltip inline-flex items-center px-2 py-0.5 rounded text-[#3e5637] text-xs font-semibold cursor-pointer transition-colors duration-200" style="background-color: #d0e7d2;" data-type="climate">
|
||||||
@@ -92,6 +97,12 @@
|
|||||||
class="inline-block bg-[#6b8f71] text-white hover:bg-[#4e6b50] font-semibold px-6 py-2 rounded-lg shadow transition-colors duration-200">
|
class="inline-block bg-[#6b8f71] text-white hover:bg-[#4e6b50] font-semibold px-6 py-2 rounded-lg shadow transition-colors duration-200">
|
||||||
🌱 View Similar Plants
|
🌱 View Similar Plants
|
||||||
</a>
|
</a>
|
||||||
|
{% if plant.section %}
|
||||||
|
<a href="{{ url_for('home', section=plant.section_id) }}"
|
||||||
|
class="inline-block bg-[#6b8f71] text-white hover:bg-[#4e6b50] font-semibold px-6 py-2 rounded-lg shadow transition-colors duration-200">
|
||||||
|
📚 View Plants in this Section
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
<a href="{{ url_for('home') }}" class="inline-block bg-[#e6ebe0] text-[#3e5637] hover:bg-[#b7c7a3] hover:text-[#4e6b50] font-semibold px-6 py-2 rounded-lg shadow transition-colors duration-200">
|
<a href="{{ url_for('home') }}" class="inline-block bg-[#e6ebe0] text-[#3e5637] hover:bg-[#b7c7a3] hover:text-[#4e6b50] font-semibold px-6 py-2 rounded-lg shadow transition-colors duration-200">
|
||||||
← Back to Home
|
← Back to Home
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user