Move profile and settings into the new unified dashboard, showing user info in one place
This commit is contained in:
parent
2d826734a0
commit
7edefe23c3
37 changed files with 726 additions and 500 deletions
179
theme/templates/account/dashboard.html
Normal file
179
theme/templates/account/dashboard.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n static crispy_forms_tags gravatar %}
|
||||
|
||||
{% block head_title %}{{ _('Dashboard') }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto" x-data="{ activeTab: '{{ active_tab|default:'dash' }}' }">
|
||||
|
||||
<!-- Tab Navigation -->
|
||||
<div class="tabs tabs-border mb-8">
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'dash'}" @click="activeTab = 'dash'">{{ _('Dash') }}</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'dashboard_offers'}" @click="activeTab = 'dashboard_offers'">{{ _('Your Trade Offers') }} ({{ dashboard_offers_paginated.paginator.count }})</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'waiting_on_you'}" @click="activeTab = 'waiting_on_you'">{{ _('Waiting on You') }} ({{ trade_acceptances_waiting_paginated.paginator.count }})</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'waiting_on_them'}" @click="activeTab = 'waiting_on_them'">{{ _('Waiting on Them') }} ({{ other_party_trade_acceptances_paginated.paginator.count }})</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'trade_history'}" @click="activeTab = 'trade_history'">{{ _('Trade History') }}</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'profile'}" @click="activeTab = 'profile'">{{ _('Profile') }}</button>
|
||||
<button type="button" :class="{'tab': true, 'tab-active': activeTab === 'settings'}" @click="activeTab = 'settings'">{{ _('Settings') }}</button>
|
||||
</div>
|
||||
|
||||
<!-- Tab Panels -->
|
||||
|
||||
<!-- Dash Tab - Dashboard Summary -->
|
||||
<div x-show="activeTab === 'dash'">
|
||||
<div class="card bg-base-100 shadow-xl mb-4">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{{ _('Account Summary') }}</h2>
|
||||
<p><strong>{{ _('Username:') }}</strong> {{ request.user.username }}</p>
|
||||
<p><strong>{{ _('Default Friend Code:') }}</strong> {{ selected_friend_code.friend_code }}</p>
|
||||
<p><strong>{{ _('Reputation Score:') }}</strong> {{ request.user.reputation_score }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-base-100 shadow-xl mb-4">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{{ _('Trade Summary') }}</h2>
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">{{ _('Your Trade Offers') }}</div>
|
||||
<div class="stat-value">{{ dashboard_offers_paginated.paginator.count }}</div>
|
||||
<div class="stat-desc">{{ _('Active Offers') }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">{{ _('Waiting on You') }}</div>
|
||||
<div class="stat-value">{{ trade_acceptances_waiting_paginated.paginator.count }}</div>
|
||||
<div class="stat-desc">{{ _('Pending Requests') }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">{{ _('Waiting on Them') }}</div>
|
||||
<div class="stat-value">{{ other_party_trade_acceptances_paginated.paginator.count }}</div>
|
||||
<div class="stat-desc">{{ _('Pending Responses') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{{ _('Quick Actions') }}</h2>
|
||||
<div class="flex space-x-4">
|
||||
<a href="{% url 'trade_offer_create' %}" class="btn btn-primary">{{ _('Create New Offer') }}</a>
|
||||
<a href="{% url 'trade_offer_list' %}" class="btn btn-secondary">{{ _('View All Offers') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Your Trade Offers Tab -->
|
||||
<div x-show="activeTab === 'dashboard_offers'" x-data="tradeOffersPagination('{% url 'dashboard' %}?ajax_section=dashboard_offers')">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=dashboard_offers_paginated %}
|
||||
</div>
|
||||
|
||||
<!-- Waiting on You Tab -->
|
||||
<div x-show="activeTab === 'waiting_on_you'" x-data="tradeOffersPagination('{% url 'dashboard' %}?ajax_section=waiting_acceptances')">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=trade_acceptances_waiting_paginated %}
|
||||
</div>
|
||||
|
||||
<!-- Waiting on Them Tab -->
|
||||
<div x-show="activeTab === 'waiting_on_them'" x-data="tradeOffersPagination('{% url 'dashboard' %}?ajax_section=other_party_acceptances')">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=other_party_trade_acceptances_paginated %}
|
||||
</div>
|
||||
|
||||
<!-- Trade History Tab -->
|
||||
<div x-show="activeTab === 'trade_history'">
|
||||
<div class="divider">{{ _('Closed Offers') }} ({{ closed_offers_paginated.paginator.count }})</div>
|
||||
<div class="mb-8">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=closed_offers_paginated %}
|
||||
</div>
|
||||
<div class="divider">{{ _('Closed Acceptances') }} ({{ closed_acceptances_paginated.paginator.count }})</div>
|
||||
<div class="mb-8">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=closed_acceptances_paginated %}
|
||||
</div>
|
||||
<div class="divider">{{ _('Rejected by Them') }} ({{ rejected_by_them_paginated.paginator.count }})</div>
|
||||
<div class="mb-8">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=rejected_by_them_paginated %}
|
||||
</div>
|
||||
<div class="divider">{{ _('Rejected by Me') }} ({{ rejected_by_me_paginated.paginator.count }})</div>
|
||||
<div class="mb-8">
|
||||
{% include 'trades/_trade_offer_list.html' with offers=rejected_by_me_paginated %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Tab -->
|
||||
<div x-show="activeTab === 'profile'">
|
||||
<div class="card card-border bg-base-100 shadow-lg mx-auto p-6 mb-4">
|
||||
{% with gravatar_profile=request.user.email|gravatar_profile_data %}
|
||||
{% if gravatar_profile %}
|
||||
<div class="hovercard-profile mb-4 text-center">
|
||||
<img src="{{ gravatar_profile.thumbnailUrl }}" alt="{{ gravatar_profile.displayName|default:request.user.username }}" class="rounded-full mb-2 mx-auto" />
|
||||
<h3 class="text-xl mb-2">{{ gravatar_profile.displayName|default:request.user.username }}</h3>
|
||||
<a href="{{ gravatar_profile.profileUrl }}" target="_blank" class="btn btn-primary">{{ _('View Gravatar Profile') }}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-center">{{ _('No Gravatar profile data available.') }}</p>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class="divider"></div>
|
||||
<h2 class="text-lg font-semibold">{{ _('What is Gravatar?') }}</h2>
|
||||
<p class="mb-4">{{ _('Gravatar (Globally Recognized Avatar) is a free service that links your email address to a profile picture and, optionally, a profile. Many websites use Gravatar to display your avatar automatically.') }}</p>
|
||||
<h2 class="text-lg font-semibold">{{ _('How does it work?') }}</h2>
|
||||
<p class="mb-4">{{ _('If you have set up a Gravatar, your profile picture will appear whenever you use your email on supported sites. Updates made on Gravatar will reflect here.') }}</p>
|
||||
<h2 class="text-lg font-semibold">{{ _('Is it safe? What about privacy?') }}</h2>
|
||||
<p class="mb-4">{{ _('Gravatar is optional, and your email is hashed to maintain privacy. Your personal data remains secure.') }}</p>
|
||||
<h2 class="text-lg font-semibold">{{ _('Want to update or add a Gravatar?') }}</h2>
|
||||
<p class="mb-4">{{ _('Go to Gravatar.com to set up or change your avatar or profile. Your changes will appear here once saved!') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Tab -->
|
||||
<div x-show="activeTab === 'settings'">
|
||||
<div class="card card-border bg-base-100 shadow-lg mx-auto p-6 mb-4">
|
||||
<form method="post" action="{% url 'dashboard' %}">
|
||||
{% csrf_token %}
|
||||
{{ settings_form|crispy }}
|
||||
<a href="{% url 'list_friend_codes' %}" class="link link-secondary">{{ _('Edit Friend Codes') }}</a>
|
||||
<button type="submit" name="update_settings" class="w-full btn btn-success mt-4">{{ _('Save Settings') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<a href="{% url 'account_logout' %}" class="btn btn-warning">{{ _('Sign Out') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function tradeOffersPagination(baseUrl) {
|
||||
return {
|
||||
baseUrl: baseUrl,
|
||||
_hasChangePageListener: false,
|
||||
loadPage(page) {
|
||||
let url = new URL(this.baseUrl, window.location.origin);
|
||||
url.searchParams.set("page", page);
|
||||
fetch(url, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
this.$el.innerHTML = html;
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
init() {
|
||||
if (!this._hasChangePageListener) {
|
||||
this.$el.addEventListener('change-page', event => {
|
||||
let page = event.detail.page;
|
||||
this.loadPage(page);
|
||||
});
|
||||
this._hasChangePageListener = true;
|
||||
}
|
||||
this.$el.querySelectorAll("a.ajax-page-link").forEach(link => {
|
||||
link.addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
let page = link.getAttribute("data-page");
|
||||
this.loadPage(page);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue