Update admin routes and domain setup page

This commit is contained in:
oguz ozturk 2026-01-12 00:18:33 +03:00
parent 2f98057b43
commit 7c334c91ac
2 changed files with 248 additions and 5 deletions

View File

@ -1,9 +1,11 @@
""" """
Admin routes - Cloudflare hesap yönetimi Admin routes - Cloudflare hesap yönetimi ve Customer yönetimi
""" """
from flask import Blueprint, request, jsonify from flask import Blueprint, request, jsonify
from app.models.domain import db, CloudflareAccount from app.models.domain import db, CloudflareAccount, Domain
from app.models.user import User, Customer
from app.services.cloudflare_service import CloudflareService from app.services.cloudflare_service import CloudflareService
from sqlalchemy import func
admin_bp = Blueprint('admin', __name__, url_prefix='/api/admin') admin_bp = Blueprint('admin', __name__, url_prefix='/api/admin')
@ -268,3 +270,216 @@ def test_cf_account(account_id):
"message": f"Test sırasında hata: {str(e)}" "message": f"Test sırasında hata: {str(e)}"
}), 500 }), 500
# ============================================
# CUSTOMER MANAGEMENT ENDPOINTS
# ============================================
@admin_bp.route('/customers', methods=['GET'])
def list_customers():
"""Tüm müşterileri listele"""
try:
# Query parameters
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 20, type=int)
search = request.args.get('search', '')
# Base query
query = db.session.query(User, Customer).join(Customer, User.id == Customer.user_id)
# Search filter
if search:
query = query.filter(
db.or_(
User.email.ilike(f'%{search}%'),
User.full_name.ilike(f'%{search}%'),
Customer.company_name.ilike(f'%{search}%')
)
)
# Pagination
total = query.count()
results = query.offset((page - 1) * per_page).limit(per_page).all()
# Format response
customers = []
for user, customer in results:
# Get domain count
domain_count = Domain.query.filter_by(customer_id=customer.id).count()
customer_data = {
**user.to_dict(),
**customer.to_dict(),
'domain_count': domain_count
}
customers.append(customer_data)
return jsonify({
"status": "success",
"customers": customers,
"pagination": {
"page": page,
"per_page": per_page,
"total": total,
"pages": (total + per_page - 1) // per_page
}
})
except Exception as e:
return jsonify({
"status": "error",
"message": f"Müşteriler listelenirken hata: {str(e)}"
}), 500
@admin_bp.route('/customers/<int:customer_id>', methods=['GET'])
def get_customer(customer_id):
"""Belirli bir müşteriyi getir"""
try:
customer = Customer.query.get(customer_id)
if not customer:
return jsonify({
"status": "error",
"message": "Müşteri bulunamadı"
}), 404
user = User.query.get(customer.user_id)
# Get domains
domains = Domain.query.filter_by(customer_id=customer.id).all()
return jsonify({
"status": "success",
"customer": {
**user.to_dict(),
**customer.to_dict(),
'domains': [d.to_dict() for d in domains]
}
})
except Exception as e:
return jsonify({
"status": "error",
"message": f"Müşteri getirilirken hata: {str(e)}"
}), 500
@admin_bp.route('/customers/<int:customer_id>/plan', methods=['PUT'])
def update_customer_plan(customer_id):
"""Müşterinin planını güncelle"""
try:
data = request.json
customer = Customer.query.get(customer_id)
if not customer:
return jsonify({
"status": "error",
"message": "Müşteri bulunamadı"
}), 404
# Update plan
if 'subscription_plan' in data:
customer.subscription_plan = data['subscription_plan']
if 'max_domains' in data:
customer.max_domains = data['max_domains']
if 'max_containers' in data:
customer.max_containers = data['max_containers']
if 'subscription_status' in data:
customer.subscription_status = data['subscription_status']
db.session.commit()
return jsonify({
"status": "success",
"message": "Plan başarıyla güncellendi",
"customer": customer.to_dict()
})
except Exception as e:
db.session.rollback()
return jsonify({
"status": "error",
"message": f"Plan güncellenirken hata: {str(e)}"
}), 500
@admin_bp.route('/customers/<int:customer_id>/status', methods=['PUT'])
def update_customer_status(customer_id):
"""Müşteri durumunu güncelle (aktif/pasif)"""
try:
data = request.json
customer = Customer.query.get(customer_id)
if not customer:
return jsonify({
"status": "error",
"message": "Müşteri bulunamadı"
}), 404
user = User.query.get(customer.user_id)
if 'is_active' in data:
user.is_active = data['is_active']
if 'subscription_status' in data:
customer.subscription_status = data['subscription_status']
db.session.commit()
return jsonify({
"status": "success",
"message": "Durum başarıyla güncellendi"
})
except Exception as e:
db.session.rollback()
return jsonify({
"status": "error",
"message": f"Durum güncellenirken hata: {str(e)}"
}), 500
@admin_bp.route('/stats', methods=['GET'])
def get_admin_stats():
"""Admin dashboard istatistikleri"""
try:
total_customers = Customer.query.count()
active_customers = db.session.query(Customer).join(User).filter(User.is_active == True).count()
total_domains = Domain.query.count()
active_domains = Domain.query.filter_by(status='active').count()
# CF accounts stats
total_cf_accounts = CloudflareAccount.query.filter_by(is_active=True).count()
# Subscription breakdown
subscription_stats = db.session.query(
Customer.subscription_plan,
func.count(Customer.id)
).group_by(Customer.subscription_plan).all()
return jsonify({
"status": "success",
"stats": {
"customers": {
"total": total_customers,
"active": active_customers
},
"domains": {
"total": total_domains,
"active": active_domains
},
"cf_accounts": total_cf_accounts,
"subscriptions": {plan: count for plan, count in subscription_stats}
}
})
except Exception as e:
return jsonify({
"status": "error",
"message": f"İstatistikler alınırken hata: {str(e)}"
}), 500

View File

@ -73,16 +73,44 @@ function DomainSetupNew() {
setStep(2) setStep(2)
} }
const handleCFAccountTypeSelect = (type) => { const handleCFAccountTypeSelect = async (type) => {
setCfAccountType(type) setCfAccountType(type)
setError(null) setError(null)
if (type === 'own') { if (type === 'own') {
setStep(3) // Go to token input setStep(3) // Go to token input
} else { } else {
// Auto-select first active company CF account
if (companyCFAccounts.length > 0) {
const firstAccount = companyCFAccounts[0]
setSelectedCFAccount(firstAccount)
// Automatically validate with company account
setLoading(true)
try {
const response = await dnsAPI.selectCompanyAccount(domain, firstAccount.id)
if (response.data.status === 'success') {
setZoneInfo(response.data)
// Check if NS is already configured
await checkNameservers()
setStep(5) // Go to NS check/instructions
} else {
setError(response.data.message || 'Şirket hesabı seçilemedi')
setStep(4) // Show account selection
}
} catch (err) {
setError('Şirket hesabı seçilirken hata oluştu')
setStep(4) // Show account selection
} finally {
setLoading(false)
}
} else {
setError('Aktif şirket CF hesabı bulunamadı')
setStep(4) // Go to company account selection setStep(4) // Go to company account selection
} }
} }
}
const handleOwnTokenValidate = async (e) => { const handleOwnTokenValidate = async (e) => {
e.preventDefault() e.preventDefault()