from flask import Blueprint, render_template, request, jsonify, make_response from app import db from app.models import Folder, User import uuid import logging main = Blueprint('main', __name__) # For prototype, use a fixed user ID MOCK_USER_ID = 1 @main.route('/') def index(): # Ensure the mock user exists user = User.query.get(MOCK_USER_ID) if not user: user = User(id=MOCK_USER_ID, email='prototype@example.com') db.session.add(user) db.session.commit() folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() return render_template('index.html', folders=folders) @main.route('/api/folders/new', methods=['GET']) def new_folder_modal(): # Return the add folder modal response = make_response(render_template('partials/folder_modal.html')) response.headers['HX-Trigger'] = 'open-modal' return response @main.route('/api/folders', methods=['POST']) def add_folder(): try: # Get form data instead of JSON name = request.form.get('name') rule_text = request.form.get('rule_text') priority = request.form.get('priority') # Server-side validation errors = {} if not name or not name.strip(): errors['name'] = 'Folder name is required' elif len(name.strip()) < 3: errors['name'] = 'Folder name must be at least 3 characters' elif len(name.strip()) > 50: errors['name'] = 'Folder name must be less than 50 characters' if not rule_text or not rule_text.strip(): errors['rule_text'] = 'Rule text is required' elif len(rule_text.strip()) < 10: errors['rule_text'] = 'Rule text must be at least 10 characters' elif len(rule_text.strip()) > 200: errors['rule_text'] = 'Rule text must be less than 200 characters' # If there are validation errors, return the modal with errors if errors: response = make_response(render_template('partials/folder_modal.html', errors=errors, name=name, rule_text=rule_text, priority=priority)) response.headers['HX-Retarget'] = '#folder-modal' response.headers['HX-Reswap'] = 'outerHTML' return response # Create new folder folder = Folder( user_id=MOCK_USER_ID, name=name.strip(), rule_text=rule_text.strip(), priority=int(priority) if priority else 0 ) db.session.add(folder) db.session.commit() # Get updated list of folders folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() # Return the updated folders list HTML response = make_response(render_template('partials/folders_list.html', folders=folders)) response.headers['HX-Trigger'] = 'close-modal' response.status_code = 201 return response except Exception as e: # Print unhandled exceptions to the console as required logging.exception("Error adding folder: %s", e) db.session.rollback() # Return error in modal errors = {'general': 'An unexpected error occurred. Please try again.'} response = make_response(render_template('partials/folder_modal.html', errors=errors, name=name, rule_text=rule_text, priority=priority)) response.headers['HX-Retarget'] = '#folder-modal' response.headers['HX-Reswap'] = 'outerHTML' return response @main.route('/api/folders/', methods=['DELETE']) def delete_folder(folder_id): try: # Find the folder by ID folder = Folder.query.filter_by(id=folder_id, user_id=MOCK_USER_ID).first() if not folder: # Folder not found folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() return render_template('partials/folders_list.html', folders=folders) # Delete the folder db.session.delete(folder) db.session.commit() # Get updated list of folders folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() # Return the updated folders list HTML return render_template('partials/folders_list.html', folders=folders) except Exception as e: # Print unhandled exceptions to the console as required logging.exception("Error deleting folder: %s", e) db.session.rollback() # Return the folders list unchanged folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() return render_template('partials/folders_list.html', folders=folders) @main.route('/api/folders//edit', methods=['GET']) def edit_folder_modal(folder_id): try: # Find the folder by ID folder = Folder.query.filter_by(id=folder_id, user_id=MOCK_USER_ID).first() if not folder: return jsonify({'error': 'Folder not found'}), 404 # Return the edit folder modal with folder data response = make_response(render_template('partials/folder_modal.html', folder=folder)) response.headers['HX-Trigger'] = 'open-modal' return response except Exception as e: # Print unhandled exceptions to the console as required logging.exception("Error getting folder for edit: %s", e) return jsonify({'error': 'Error retrieving folder'}), 500 @main.route('/api/folders/', methods=['PUT']) def update_folder(folder_id): try: # Find the folder by ID folder = Folder.query.filter_by(id=folder_id, user_id=MOCK_USER_ID).first() if not folder: # Folder not found folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() return render_template('partials/folders_list.html', folders=folders) # Get form data name = request.form.get('name') rule_text = request.form.get('rule_text') priority = request.form.get('priority') # Server-side validation errors = {} if not name or not name.strip(): errors['name'] = 'Folder name is required' elif len(name.strip()) < 3: errors['name'] = 'Folder name must be at least 3 characters' elif len(name.strip()) > 50: errors['name'] = 'Folder name must be less than 50 characters' if not rule_text or not rule_text.strip(): errors['rule_text'] = 'Rule text is required' elif len(rule_text.strip()) < 10: errors['rule_text'] = 'Rule text must be at least 10 characters' elif len(rule_text.strip()) > 200: errors['rule_text'] = 'Rule text must be less than 200 characters' # If there are validation errors, return the modal with errors if errors: response = make_response(render_template('partials/folder_modal.html', folder=folder, errors=errors, name=name, rule_text=rule_text, priority=priority)) response.headers['HX-Retarget'] = '#folder-modal' response.headers['HX-Reswap'] = 'outerHTML' return response # Update folder folder.name = name.strip() folder.rule_text = rule_text.strip() folder.priority = int(priority) if priority else 0 db.session.commit() # Get updated list of folders folders = Folder.query.filter_by(user_id=MOCK_USER_ID).all() response = make_response(render_template('partials/folders_list.html', folders=folders)) response.headers['HX-Trigger'] = 'close-modal' return response except Exception as e: # Print unhandled exceptions to the console as required logging.exception("Error updating folder: %s", e) db.session.rollback() # Return error in modal errors = {'general': 'An unexpected error occurred. Please try again.'} response = make_response(render_template('partials/folder_modal.html', folder=folder, errors=errors, name=name, rule_text=rule_text, priority=priority)) response.headers['HX-Retarget'] = '#folder-modal' response.headers['HX-Reswap'] = 'outerHTML' return response