bounty board feature buyers to see bounty boards seller profile page (like have theme chooser) Have the game and set name be filters. Add cards to vault manually update card inventory add to have the autocomplete for the card - store analytics, clicks, views, link to store (url/QR code) bulk item inventory creation -- Make the banner feature flag driven so I can have a beta site setup like the primary site don't use primary key values in urls - update to use uuid4 values site analytics. tianji is being sent item potent on the mtg and lorcana populate scripts Card item images for specific listings check that when you buy a card it is in the vault Buys should be able to search on store inventories More pie charts for the seller! post bounty board is slow to load seller reviews/ratings - show a historgram - need a way for someone to rate Report a seller feature for buyer to report Make sure the stlying is consistent based on the theme choosen smart minimum order quantity and shipping amounts (defined by the store itself) put virtual packs behind a feature flag like bounty board proxy service feature flag Terms of Service new description for TCGKof store SSN, ITIN, and EIN optomize for SEO
191 lines
6.8 KiB
Python
191 lines
6.8 KiB
Python
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.http import JsonResponse
|
|
from django.contrib.auth import login
|
|
from .forms import CustomUserCreationForm, ProfileForm, AddressForm, PaymentMethodForm
|
|
from django.views.generic import CreateView
|
|
from django.urls import reverse_lazy
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib import messages
|
|
from .models import User, Address, PaymentMethod
|
|
from store.models import VaultItem, Set, Card
|
|
|
|
class RegisterView(CreateView):
|
|
model = User
|
|
form_class = CustomUserCreationForm
|
|
template_name = 'users/register.html'
|
|
success_url = reverse_lazy('users:login_success')
|
|
|
|
def form_valid(self, form):
|
|
user = form.save()
|
|
# Create Buyer profile for every new user registered via this form
|
|
from .models import Buyer
|
|
Buyer.objects.create(user=user)
|
|
|
|
login(self.request, user)
|
|
return redirect('users:login_success')
|
|
|
|
@login_required
|
|
def seller_dashboard_view(request):
|
|
return render(request, 'users/seller_dashboard.html')
|
|
|
|
@login_required
|
|
def login_success_view(request):
|
|
if hasattr(request.user, 'profile') and request.user.profile.is_seller:
|
|
return redirect('store:seller_dashboard')
|
|
return redirect('home')
|
|
|
|
@login_required
|
|
def profile_view(request):
|
|
if request.method == 'POST':
|
|
form = ProfileForm(request.POST, instance=request.user.profile)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, 'Profile updated successfully.')
|
|
return redirect('users:profile')
|
|
else:
|
|
form = ProfileForm(instance=request.user.profile)
|
|
|
|
# Order filtering
|
|
orders = []
|
|
if hasattr(request.user, 'buyer_profile'):
|
|
orders = request.user.buyer_profile.orders.all().order_by('-created_at')
|
|
|
|
date_query = request.GET.get('date')
|
|
if date_query and orders:
|
|
orders = orders.filter(created_at__date=date_query)
|
|
|
|
addresses = request.user.addresses.all()
|
|
payment_methods = request.user.payment_methods.all()
|
|
|
|
return render(request, 'users/profile.html', {
|
|
'user': request.user,
|
|
'form': form,
|
|
'orders': orders,
|
|
'date_query': date_query,
|
|
'addresses': addresses,
|
|
'payment_methods': payment_methods,
|
|
})
|
|
|
|
@login_required
|
|
def upgrade_account_view(request):
|
|
if request.method == 'POST':
|
|
# Mock payment processing would go here
|
|
profile = request.user.profile
|
|
profile.is_pro = True
|
|
profile.save()
|
|
messages.success(request, 'Account upgraded to Pro!')
|
|
return redirect('users:profile')
|
|
return redirect('users:profile')
|
|
|
|
@login_required
|
|
def add_address_view(request):
|
|
if request.method == 'POST':
|
|
form = AddressForm(request.POST)
|
|
if form.is_valid():
|
|
address = form.save(commit=False)
|
|
address.user = request.user
|
|
if address.is_default:
|
|
# Unset previous default
|
|
Address.objects.filter(user=request.user, address_type=address.address_type, is_default=True).update(is_default=False)
|
|
address.save()
|
|
messages.success(request, 'Address added successfully.')
|
|
return redirect('users:profile')
|
|
else:
|
|
form = AddressForm()
|
|
return render(request, 'users/address_form.html', {'form': form})
|
|
|
|
@login_required
|
|
def delete_address_view(request, pk):
|
|
address = get_object_or_404(Address, pk=pk, user=request.user)
|
|
if request.method == 'POST':
|
|
address.delete()
|
|
messages.success(request, 'Address deleted.')
|
|
return redirect('users:profile')
|
|
|
|
@login_required
|
|
def add_payment_method_view(request):
|
|
if request.method == 'POST':
|
|
form = PaymentMethodForm(request.POST)
|
|
if form.is_valid():
|
|
pm = form.save(commit=False)
|
|
pm.user = request.user
|
|
if pm.is_default:
|
|
PaymentMethod.objects.filter(user=request.user, is_default=True).update(is_default=False)
|
|
pm.save()
|
|
messages.success(request, 'Payment method added successfully.')
|
|
return redirect('users:profile')
|
|
else:
|
|
form = PaymentMethodForm()
|
|
return render(request, 'users/payment_form.html', {'form': form})
|
|
|
|
@login_required
|
|
def delete_payment_method_view(request, pk):
|
|
pm = get_object_or_404(PaymentMethod, pk=pk, user=request.user)
|
|
if request.method == 'POST':
|
|
pm.delete()
|
|
messages.success(request, 'Payment method deleted.')
|
|
return redirect('users:profile')
|
|
|
|
@login_required
|
|
def vault_view(request):
|
|
if not hasattr(request.user, 'buyer_profile'):
|
|
# If not a buyer (e.g. seller), maybe show empty or redirect?
|
|
# For now, let's just show empty list
|
|
vault_items = VaultItem.objects.none()
|
|
else:
|
|
vault_items = VaultItem.objects.filter(buyer=request.user.buyer_profile).select_related('card', 'card__set').order_by('-added_at')
|
|
|
|
# Filtering
|
|
set_id = request.GET.get('set')
|
|
rarity = request.GET.get('rarity')
|
|
search_query = request.GET.get('q')
|
|
|
|
if search_query:
|
|
vault_items = vault_items.filter(card__name__icontains=search_query)
|
|
|
|
if set_id:
|
|
vault_items = vault_items.filter(card__set_id=set_id)
|
|
if rarity:
|
|
vault_items = vault_items.filter(card__rarity=rarity)
|
|
|
|
total_cards = sum(item.quantity for item in vault_items)
|
|
|
|
# Get options for filters
|
|
# We only want sets and rarities that are actually in the user's vault
|
|
if hasattr(request.user, 'buyer_profile'):
|
|
user_card_ids = VaultItem.objects.filter(buyer=request.user.buyer_profile).values_list('card_id', flat=True)
|
|
else:
|
|
user_card_ids = []
|
|
available_sets = Set.objects.filter(cards__id__in=user_card_ids).distinct()
|
|
available_rarities = Card.objects.filter(id__in=user_card_ids).values_list('rarity', flat=True).distinct()
|
|
|
|
return render(request, 'users/vault.html', {
|
|
'vault_items': vault_items,
|
|
'total_cards': total_cards,
|
|
'available_sets': available_sets,
|
|
'available_rarities': available_rarities,
|
|
'current_set': int(set_id) if set_id else None,
|
|
'current_rarity': rarity,
|
|
'search_query': search_query
|
|
})
|
|
|
|
@login_required
|
|
def vault_autocomplete(request):
|
|
if not hasattr(request.user, 'buyer_profile'):
|
|
return JsonResponse({'results': []})
|
|
|
|
query = request.GET.get('q', '')
|
|
if len(query) < 2:
|
|
return JsonResponse({'results': []})
|
|
|
|
# Filter items in user's vault matching the query
|
|
items = VaultItem.objects.filter(
|
|
buyer=request.user.buyer_profile,
|
|
card__name__icontains=query
|
|
).values_list('card__name', flat=True).distinct()[:10]
|
|
|
|
return JsonResponse({'results': list(items)})
|
|
|
|
def sell_on_tcgkof_view(request):
|
|
return render(request, 'users/sell_on_tcgkof.html')
|