Update admin routes and domain setup page
This commit is contained in:
parent
2f98057b43
commit
7c334c91ac
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue