- Przycisk usuwania ogłoszenia z potwierdzeniem - Przycisk aktywacji/dezaktywacji ogłoszenia - Endpointy: /delete, /toggle-active - Badge "Nieaktywne" dla dezaktywowanych ogłoszeń Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
200 lines
6.2 KiB
Python
200 lines
6.2 KiB
Python
"""
|
|
Classifieds Routes
|
|
==================
|
|
|
|
B2B bulletin board endpoints.
|
|
"""
|
|
|
|
from datetime import datetime, timedelta
|
|
from flask import render_template, request, redirect, url_for, flash, jsonify
|
|
from flask_login import login_required, current_user
|
|
|
|
from . import bp
|
|
from database import SessionLocal, Classified
|
|
from utils.helpers import sanitize_input
|
|
|
|
|
|
@bp.route('/', endpoint='classifieds_index')
|
|
@login_required
|
|
def index():
|
|
"""Tablica ogłoszeń B2B"""
|
|
listing_type = request.args.get('type', '')
|
|
category = request.args.get('category', '')
|
|
page = request.args.get('page', 1, type=int)
|
|
per_page = 20
|
|
|
|
db = SessionLocal()
|
|
try:
|
|
query = db.query(Classified).filter(
|
|
Classified.is_active == True
|
|
)
|
|
|
|
# Filtry
|
|
if listing_type:
|
|
query = query.filter(Classified.listing_type == listing_type)
|
|
if category:
|
|
query = query.filter(Classified.category == category)
|
|
|
|
# Sortowanie - najnowsze pierwsze
|
|
query = query.order_by(Classified.created_at.desc())
|
|
|
|
total = query.count()
|
|
classifieds = query.limit(per_page).offset((page - 1) * per_page).all()
|
|
|
|
# Kategorie do filtrów
|
|
categories = [
|
|
('uslugi', 'Usługi'),
|
|
('produkty', 'Produkty'),
|
|
('wspolpraca', 'Współpraca'),
|
|
('praca', 'Praca'),
|
|
('inne', 'Inne')
|
|
]
|
|
|
|
return render_template('classifieds/index.html',
|
|
classifieds=classifieds,
|
|
categories=categories,
|
|
listing_type=listing_type,
|
|
category_filter=category,
|
|
page=page,
|
|
total_pages=(total + per_page - 1) // per_page
|
|
)
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@bp.route('/nowe', methods=['GET', 'POST'], endpoint='classifieds_new')
|
|
@login_required
|
|
def new():
|
|
"""Dodaj nowe ogłoszenie"""
|
|
if request.method == 'POST':
|
|
listing_type = request.form.get('listing_type', '')
|
|
category = request.form.get('category', '')
|
|
title = sanitize_input(request.form.get('title', ''), 255)
|
|
description = request.form.get('description', '').strip()
|
|
budget_info = sanitize_input(request.form.get('budget_info', ''), 255)
|
|
location_info = sanitize_input(request.form.get('location_info', ''), 255)
|
|
|
|
if not listing_type or not category or not title or not description:
|
|
flash('Wszystkie wymagane pola muszą być wypełnione.', 'error')
|
|
return render_template('classifieds/new.html')
|
|
|
|
db = SessionLocal()
|
|
try:
|
|
# Automatyczne wygaśnięcie po 30 dniach
|
|
expires = datetime.now() + timedelta(days=30)
|
|
|
|
classified = Classified(
|
|
author_id=current_user.id,
|
|
company_id=current_user.company_id,
|
|
listing_type=listing_type,
|
|
category=category,
|
|
title=title,
|
|
description=description,
|
|
budget_info=budget_info,
|
|
location_info=location_info,
|
|
expires_at=expires
|
|
)
|
|
db.add(classified)
|
|
db.commit()
|
|
|
|
flash('Ogłoszenie dodane.', 'success')
|
|
return redirect(url_for('.classifieds_index'))
|
|
finally:
|
|
db.close()
|
|
|
|
return render_template('classifieds/new.html')
|
|
|
|
|
|
@bp.route('/<int:classified_id>', endpoint='classifieds_view')
|
|
@login_required
|
|
def view(classified_id):
|
|
"""Szczegóły ogłoszenia"""
|
|
db = SessionLocal()
|
|
try:
|
|
classified = db.query(Classified).filter(
|
|
Classified.id == classified_id
|
|
).first()
|
|
|
|
if not classified:
|
|
flash('Ogłoszenie nie istnieje.', 'error')
|
|
return redirect(url_for('.classifieds_index'))
|
|
|
|
# Zwiększ licznik wyświetleń (handle NULL)
|
|
classified.views_count = (classified.views_count or 0) + 1
|
|
db.commit()
|
|
|
|
return render_template('classifieds/view.html', classified=classified)
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@bp.route('/<int:classified_id>/zakoncz', methods=['POST'], endpoint='classifieds_close')
|
|
@login_required
|
|
def close(classified_id):
|
|
"""Zamknij ogłoszenie"""
|
|
db = SessionLocal()
|
|
try:
|
|
classified = db.query(Classified).filter(
|
|
Classified.id == classified_id,
|
|
Classified.author_id == current_user.id
|
|
).first()
|
|
|
|
if not classified:
|
|
return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje lub brak uprawnień'}), 404
|
|
|
|
classified.is_active = False
|
|
db.commit()
|
|
|
|
return jsonify({'success': True, 'message': 'Ogłoszenie zamknięte'})
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@bp.route('/<int:classified_id>/delete', methods=['POST'], endpoint='classifieds_delete')
|
|
@login_required
|
|
def delete(classified_id):
|
|
"""Usuń ogłoszenie (admin only)"""
|
|
if not current_user.is_admin:
|
|
return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403
|
|
|
|
db = SessionLocal()
|
|
try:
|
|
classified = db.query(Classified).filter(
|
|
Classified.id == classified_id
|
|
).first()
|
|
|
|
if not classified:
|
|
return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404
|
|
|
|
db.delete(classified)
|
|
db.commit()
|
|
|
|
return jsonify({'success': True, 'message': 'Ogłoszenie usunięte'})
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@bp.route('/<int:classified_id>/toggle-active', methods=['POST'], endpoint='classifieds_toggle_active')
|
|
@login_required
|
|
def toggle_active(classified_id):
|
|
"""Aktywuj/dezaktywuj ogłoszenie (admin only)"""
|
|
if not current_user.is_admin:
|
|
return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403
|
|
|
|
db = SessionLocal()
|
|
try:
|
|
classified = db.query(Classified).filter(
|
|
Classified.id == classified_id
|
|
).first()
|
|
|
|
if not classified:
|
|
return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404
|
|
|
|
classified.is_active = not classified.is_active
|
|
db.commit()
|
|
|
|
status = 'aktywowane' if classified.is_active else 'dezaktywowane'
|
|
return jsonify({'success': True, 'message': f'Ogłoszenie {status}', 'is_active': classified.is_active})
|
|
finally:
|
|
db.close()
|