Refactor email templates

This commit is contained in:
badblocks 2025-04-07 18:33:45 -07:00
parent e37731b74d
commit 32da8157a6
31 changed files with 476 additions and 2516 deletions

View file

@ -17,7 +17,7 @@ class CustomUser(AbstractUser):
verbose_name="Show Friend Code on Link Previews", verbose_name="Show Friend Code on Link Previews",
help_text="This will primarily affect share link previews on X, Discord, etc." help_text="This will primarily affect share link previews on X, Discord, etc."
) )
reputation_score = models.PositiveIntegerField(default=0) reputation_score = models.IntegerField(default=0)
def __str__(self): def __str__(self):
return self.email return self.email

View file

@ -1,82 +1,129 @@
[ [
{ {
"model": "accounts.customuser", "model": "accounts.customuser",
"pk": 1, "pk": 1,
"fields": { "fields": {
"password": "pbkdf2_sha256$870000$f99EReOECF2LPne1JHADoy$pr/769omIyRNkDhaojgIIm8kZcAeFiR0DOLcUvbLlk4=", "password": "pbkdf2_sha256$870000$f99EReOECF2LPne1JHADoy$pr/769omIyRNkDhaojgIIm8kZcAeFiR0DOLcUvbLlk4=",
"last_login": "2025-03-13T04:24:11.029Z", "last_login": "2025-04-07T07:40:57.629Z",
"is_superuser": true, "is_superuser": true,
"username": "badblocks", "username": "badblocks",
"first_name": "", "first_name": "",
"last_name": "", "last_name": "",
"email": "rob@badblocks.email", "email": "rob@badblocks.email",
"is_staff": true, "is_staff": true,
"is_active": true, "is_active": true,
"date_joined": "2025-03-13T04:21:04.553Z", "date_joined": "2025-03-13T04:21:04.553Z",
"default_friend_code": 1, "default_friend_code": 1,
"groups": [], "show_friend_code_on_link_previews": true,
"user_permissions": [] "reputation_score": 2,
"groups": [],
"user_permissions": []
}
},
{
"model": "accounts.customuser",
"pk": 2,
"fields": {
"password": "pbkdf2_sha256$870000$NxQDOyPzAvM3FgLL5z0SRy$JuET4f8HI55Oy1umkzg6WtjFVpYTt+UfpZWqPff4EO4=",
"last_login": "2025-03-13T04:52:57.949Z",
"is_superuser": false,
"username": "nathanward2016@gmail.com",
"first_name": "",
"last_name": "",
"email": "nathanward2016@gmail.com",
"is_staff": false,
"is_active": true,
"date_joined": "2025-03-13T04:52:28.482Z",
"default_friend_code": 2,
"show_friend_code_on_link_previews": false,
"reputation_score": 0,
"groups": [],
"user_permissions": []
}
},
{
"model": "accounts.customuser",
"pk": 3,
"fields": {
"password": "pbkdf2_sha256$870000$hbzakvek5c6oJWJ0jMliuz$4yX2/s9BsZ2FqMnOaApWQUraB+FX0JK7RmjjPbaLlgQ=",
"last_login": "2025-04-07T23:30:40.481Z",
"is_superuser": false,
"username": "badblocks2",
"first_name": "",
"last_name": "",
"email": "rob2@badblocks.email",
"is_staff": false,
"is_active": true,
"date_joined": "2025-04-07T07:36:12.011Z",
"default_friend_code": 3,
"show_friend_code_on_link_previews": false,
"reputation_score": 2,
"groups": [],
"user_permissions": []
}
},
{
"model": "accounts.friendcode",
"pk": 1,
"fields": {
"friend_code": "9167-8051-9691-8032",
"in_game_name": "badblocks",
"user": 1,
"created_at": "2025-03-13T04:21:05.166Z",
"updated_at": "2025-03-13T04:21:05.166Z"
}
},
{
"model": "accounts.friendcode",
"pk": 2,
"fields": {
"friend_code": "1234-2938-7848-7636",
"in_game_name": "backrolls",
"user": 2,
"created_at": "2025-03-13T04:52:29.166Z",
"updated_at": "2025-03-13T04:52:29.166Z"
}
},
{
"model": "accounts.friendcode",
"pk": 3,
"fields": {
"friend_code": "0987-0987-1234-1234",
"in_game_name": "badblocks2",
"user": 3,
"created_at": "2025-04-07T07:36:12.592Z",
"updated_at": "2025-04-07T07:36:12.592Z"
}
},
{
"model": "account.emailaddress",
"pk": 1,
"fields": {
"user": 1,
"email": "rob@badblocks.email",
"verified": true,
"primary": true
}
},
{
"model": "account.emailaddress",
"pk": 2,
"fields": {
"user": 2,
"email": "nathanward2016@gmail.com",
"verified": true,
"primary": true
}
},
{
"model": "account.emailaddress",
"pk": 3,
"fields": {
"user": 3,
"email": "rob2@badblocks.email",
"verified": true,
"primary": true
}
} }
}, ]
{
"model": "accounts.customuser",
"pk": 2,
"fields": {
"password": "pbkdf2_sha256$870000$NxQDOyPzAvM3FgLL5z0SRy$JuET4f8HI55Oy1umkzg6WtjFVpYTt+UfpZWqPff4EO4=",
"last_login": "2025-03-13T04:52:57.949Z",
"is_superuser": false,
"username": "nathanward2016@gmail.com",
"first_name": "",
"last_name": "",
"email": "nathanward2016@gmail.com",
"is_staff": false,
"is_active": true,
"date_joined": "2025-03-13T04:52:28.482Z",
"default_friend_code": 2,
"groups": [],
"user_permissions": []
}
},
{
"model": "accounts.friendcode",
"pk": 1,
"fields": {
"friend_code": "9167-8051-9691-8032",
"in_game_name": "badblocks",
"user": 1,
"created_at": "2025-03-13T04:21:05.166Z",
"updated_at": "2025-03-13T04:21:05.166Z"
}
},
{
"model": "accounts.friendcode",
"pk": 2,
"fields": {
"friend_code": "1234-2938-7848-7636",
"in_game_name": "backrolls",
"user": 2,
"created_at": "2025-03-13T04:52:29.166Z",
"updated_at": "2025-03-13T04:52:29.166Z"
}
},
{
"model": "account.emailaddress",
"pk": 1,
"fields": {
"user": 1,
"email": "rob@badblocks.email",
"verified": true,
"primary": true
}
},
{
"model": "account.emailaddress",
"pk": 2,
"fields": {
"user": 2,
"email": "nathanward2016@gmail.com",
"verified": true,
"primary": true
}
}
]

View file

@ -1168,7 +1168,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 236, "card": 236,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1178,7 +1178,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 545, "card": 545,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1188,7 +1188,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 537, "card": 537,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1198,7 +1198,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 248, "card": 248,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1218,7 +1218,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 533, "card": 533,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1248,7 +1248,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 543, "card": 543,
"quantity": 3, "quantity": 3,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1258,7 +1258,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 655, "card": 655,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1268,7 +1268,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 542, "card": 542,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1278,7 +1278,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 360, "card": 360,
"quantity": 2, "quantity": 2,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1298,7 +1298,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 240, "card": 240,
"quantity": 2, "quantity": 2,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -1308,7 +1308,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 657, "card": 657,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2028,7 +2028,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 227, "card": 227,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2038,7 +2038,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 530, "card": 530,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2058,7 +2058,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 540, "card": 540,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2068,7 +2068,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 239, "card": 239,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2078,7 +2078,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 244, "card": 244,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2088,7 +2088,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 539, "card": 539,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2128,7 +2128,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 532, "card": 532,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2168,7 +2168,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 535, "card": 535,
"quantity": 3, "quantity": 3,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2178,7 +2178,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 237, "card": 237,
"quantity": 1, "quantity": 1,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2188,7 +2188,7 @@
"trade_offer": 33, "trade_offer": 33,
"card": 544, "card": 544,
"quantity": 4, "quantity": 4,
"qty_accepted": 0 "qty_accepted": 1
} }
}, },
{ {
@ -2228,7 +2228,218 @@
"trade_offer": 33, "trade_offer": 33,
"card": 750, "card": 750,
"quantity": 2, "quantity": 2,
"qty_accepted": 0 "qty_accepted": 1
}
},
{
"model": "trades.tradeacceptance",
"pk": 1,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 542,
"offered_card": 532,
"state": "ACCEPTED",
"hash": "202ffbd4y",
"created_at": "2025-04-07T07:37:58.330Z",
"updated_at": "2025-04-07T07:37:58.330Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 2,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 236,
"offered_card": 530,
"state": "SENT",
"hash": "4ecac062y",
"created_at": "2025-04-07T07:38:40.854Z",
"updated_at": "2025-04-07T07:38:40.854Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 3,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 655,
"offered_card": 237,
"state": "THANKED_BY_INITIATOR",
"hash": "7ae69e4fy",
"created_at": "2025-04-07T07:38:58.971Z",
"updated_at": "2025-04-07T07:38:58.971Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 4,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 360,
"offered_card": 227,
"state": "SENT",
"hash": "a8d73a5ay",
"created_at": "2025-04-07T07:39:56.519Z",
"updated_at": "2025-04-07T07:39:56.519Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 5,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 533,
"offered_card": 539,
"state": "THANKED_BY_BOTH",
"hash": "873e6f61y",
"created_at": "2025-04-07T07:40:18.977Z",
"updated_at": "2025-04-07T07:40:18.977Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 6,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 543,
"offered_card": 540,
"state": "THANKED_BY_ACCEPTOR",
"hash": "9cdb8cc2y",
"created_at": "2025-04-07T07:40:37.114Z",
"updated_at": "2025-04-07T07:40:37.114Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 7,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 248,
"offered_card": 535,
"state": "RECEIVED",
"hash": "8da2e2e8y",
"created_at": "2025-04-07T07:46:45.763Z",
"updated_at": "2025-04-07T07:46:45.763Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 8,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 240,
"offered_card": 544,
"state": "THANKED_BY_BOTH",
"hash": "25c904e6y",
"created_at": "2025-04-07T07:47:08.427Z",
"updated_at": "2025-04-07T07:47:08.427Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 9,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 228,
"offered_card": 535,
"state": "REJECTED_BY_INITIATOR",
"hash": "1720d735y",
"created_at": "2025-04-07T07:47:35.798Z",
"updated_at": "2025-04-07T07:47:35.798Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 10,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 240,
"offered_card": 535,
"state": "REJECTED_BY_INITIATOR",
"hash": "d02caf35y",
"created_at": "2025-04-07T07:47:59.390Z",
"updated_at": "2025-04-07T07:47:59.390Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 11,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 748,
"offered_card": 750,
"state": "REJECTED_BY_ACCEPTOR",
"hash": "ea50fa4ey",
"created_at": "2025-04-07T07:48:30.600Z",
"updated_at": "2025-04-07T07:48:30.600Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 12,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 235,
"offered_card": 529,
"state": "REJECTED_BY_ACCEPTOR",
"hash": "a77cb744y",
"created_at": "2025-04-07T07:48:47.966Z",
"updated_at": "2025-04-07T07:48:47.966Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 13,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 537,
"offered_card": 239,
"state": "ACCEPTED",
"hash": "ac8d996by",
"created_at": "2025-04-07T23:31:50.450Z",
"updated_at": "2025-04-07T23:31:50.450Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 14,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 545,
"offered_card": 244,
"state": "ACCEPTED",
"hash": "01463b9dy",
"created_at": "2025-04-07T23:36:49.271Z",
"updated_at": "2025-04-07T23:36:49.271Z"
}
},
{
"model": "trades.tradeacceptance",
"pk": 15,
"fields": {
"trade_offer": 33,
"accepted_by": 3,
"requested_card": 657,
"offered_card": 750,
"state": "ACCEPTED",
"hash": "97343361y",
"created_at": "2025-04-08T01:41:36.782Z",
"updated_at": "2025-04-08T01:41:36.782Z"
} }
} }
] ]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
Happy trading!
PKMN Trade Club

View file

@ -0,0 +1 @@
Hello {{ recipient_user }},

View file

@ -0,0 +1 @@
[PKMN Trade Club]

View file

@ -0,0 +1,15 @@
{% include 'email/common/header.txt' %}
Great news! {{ acting_user }} ({{ acting_user_ign }} {{ acting_user_friend_code }}) has accepted your trade offer.
Trade Details:
- They have: {{ want_card }}
- They want: {{ has_card }}
(#{{ hash }})
What's next? You can now mark the trade as "Sent" once you've offered the card to them in the app, or reject the trade if needed.
Visit your dashboard to manage this trade:
{{ domain }}{% url 'dashboard' %}
{% include 'email/common/footer.txt' %}

View file

@ -0,0 +1 @@
Trade Accepted

View file

@ -0,0 +1,15 @@
{% include 'email/common/header.txt' %}
Great news! {{ acting_user }} ({{ acting_user_ign }} {{ acting_user_friend_code }}) has marked your trade as "Received".
Trade Details:
- They sent: {{ want_card }}
- They received: {{ has_card }}
(#{{ hash }})
What's next? Send a thank you to this user to increase their reputation!
Visit your dashboard to send thanks:
{{ domain }}{% url 'dashboard' %}
{% include 'email/common/footer.txt' %}

View file

@ -0,0 +1 @@
Trade Received

View file

@ -1,16 +1,15 @@
Hello {{ recipient_user }}, {% include 'email/common/header.txt' %}
We're sorry to inform you that {{ acting_user }} ({{ acting_user_friend_code }}) has canceled their trade acceptance. We're sorry to inform you that {{ acting_user }} ({{ acting_user_friend_code }}) has canceled their trade acceptance.
Trade Details: Trade Details:
- #{{ hash }} - They had: {{ want_card }}
- Card you were going to send: {{ has_card }} - They wanted: {{ has_card }}
- Card they were offering: {{ want_card }} (#{{ hash }})
Your trade offer is still active and available for other users to accept. Your trade offer is still active and available for other users to accept.
Visit your dashboard to manage your trade offers: Visit your dashboard to manage your trade offers:
{% url 'dashboard' %} {{ domain }}{% url 'dashboard' %}
Happy trading! {% include 'email/common/footer.txt' %}
PKMN Trade Club

View file

@ -0,0 +1 @@
Trade Was Rejected

View file

@ -1,16 +1,15 @@
Hello {{ recipient_user }}, {% include 'email/common/header.txt' %}
We're sorry to inform you that {{ acting_user }} ({{ acting_user_friend_code }}) has rejected the trade. We're sorry to inform you that {{ acting_user }} ({{ acting_user_friend_code }}) has rejected the trade.
Trade Details: Trade Details:
- #{{ hash }} - You had: {{ has_card }}
- Card you were going to receive: {{ has_card }} - You wanted: {{ want_card }}
- Card you were offering: {{ want_card }} (#{{ hash }})
Don't worry - there are plenty of other trade opportunities available! You can browse our marketplace for similar trades. Don't worry - there are plenty of other trade opportunities available! You can browse our marketplace for similar trades.
Visit the marketplace: Visit the marketplace:
https://pkmntrade.club{% url 'trade_offer_list' %} {{ domain }}{% url 'trade_offer_list' %}
Better luck with your next trade! {% include 'email/common/footer.txt' %}
PKMN Trade Club

View file

@ -0,0 +1 @@
Trade Was Rejected

View file

@ -0,0 +1,15 @@
{% include 'email/common/header.txt' %}
{{ acting_user }} ({{ acting_user_ign }} {{ acting_user_friend_code }}) has marked your trade as "Sent".
Trade Details:
- You have: {{ want_card }}
- You want: {{ has_card }}
(#{{ hash }})
What's next? Once you respond to the trade in the app, please mark the trade as "Received" in your dashboard.
Visit your dashboard to manage this trade:
{{ domain }}{% url 'dashboard' %}
{% include 'email/common/footer.txt' %}

View file

@ -0,0 +1 @@
Trade Sent

View file

@ -1,16 +1,15 @@
Hello {{ recipient_user }}, {% include 'email/common/header.txt' %}
{{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade! {{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade!
Trade Details: Trade Details:
- #{{ hash }} - They sent: {{ want_card }}
- Card you sent: {{ has_card }} - They received: {{ has_card }}
- Card they offered: {{ want_card }} (#{{ hash }})
What's next? Send a thank you to this user to increase their reputation! What's next? Send a thank you to this user to increase their reputation!
Visit your dashboard to send thanks: Visit your dashboard to send thanks:
{% url 'dashboard' %} {{ domain }}{% url 'dashboard' %}
Happy trading! {% include 'email/common/footer.txt' %}
PKMN Trade Club

View file

@ -0,0 +1 @@
You Received A Thanks!

View file

@ -0,0 +1,14 @@
{% include 'email/common/header.txt' %}
{{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade!
Trade Details:
- {% if is_initiator %}They sent: {{ has_card }}{% else %}You sent: {{ want_card }}{% endif %}
- {% if is_initiator %}They received: {{ want_card }}{% else %}You received: {{ has_card }}{% endif %}
(#{{ hash }})
This trade is now completed; no further actions can be made.
Thank you for using PKMN Trade Club.
{% include 'email/common/footer.txt' %}

View file

@ -0,0 +1 @@
You Received A Thanks!

View file

@ -1,16 +1,15 @@
Hello {{ recipient_user }}, {% include 'email/common/header.txt' %}
{{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade! {{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade!
Trade Details: Trade Details:
- #{{ hash }} - You sent: {{ want_card }}
- Card they sent: {{ has_card }} - You received: {{ has_card }}
- Card you offered: {{ want_card }} (#{{ hash }})
What's next? Send a thank you to this user to increase their reputation! What's next? Send a thank you to this user to increase their reputation!
Visit your dashboard to send thanks: Visit your dashboard to send thanks:
{% url 'dashboard' %} {{ domain }}{% url 'dashboard' %}
Happy trading! {% include 'email/common/footer.txt' %}
PKMN Trade Club

View file

@ -0,0 +1 @@
You Received A Thanks!

View file

@ -47,7 +47,7 @@
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Offered</h5> <h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Offered</h5>
</div> </div>
<div class="card-body my-4 p-0"> <div class="card-body my-4 p-0">
{% cache 3600 most_offered_cards %} {% cache 300 most_offered_cards %}
{% include "home/_card_list.html" with cards=most_offered_cards %} {% include "home/_card_list.html" with cards=most_offered_cards %}
{% endcache %} {% endcache %}
</div> </div>
@ -60,7 +60,7 @@
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Wanted</h5> <h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Wanted</h5>
</div> </div>
<div class="card-body my-4 p-0"> <div class="card-body my-4 p-0">
{% cache 3600 most_wanted_cards %} {% cache 300 most_wanted_cards %}
{% include "home/_card_list.html" with cards=most_wanted_cards %} {% include "home/_card_list.html" with cards=most_wanted_cards %}
{% endcache %} {% endcache %}
</div> </div>
@ -73,7 +73,7 @@
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Least Offered</h5> <h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Least Offered</h5>
</div> </div>
<div class="card-body my-4 p-0"> <div class="card-body my-4 p-0">
{% cache 3600 least_offered_cards %} {% cache 300 least_offered_cards %}
{% include "home/_card_list.html" with cards=least_offered_cards %} {% include "home/_card_list.html" with cards=least_offered_cards %}
{% endcache %} {% endcache %}
</div> </div>
@ -87,7 +87,6 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Featured Offers --> <!-- Featured Offers -->
<div> <div>
{% cache 3600 featured_offers %}
<div class="p-4 text-center "> <div class="p-4 text-center ">
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Featured Offers</h5> <h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Featured Offers</h5>
</div> </div>
@ -102,12 +101,10 @@
<p class="text-center">No featured offers available.</p> <p class="text-center">No featured offers available.</p>
{% endif %} {% endif %}
</div> </div>
{% endcache %}
</div> </div>
<!-- Recent Offers --> <!-- Recent Offers -->
<div> <div>
{% cache 3600 recent_offers %}
<div class="text-center p-4"> <div class="text-center p-4">
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Recent Offers</h5> <h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Recent Offers</h5>
</div> </div>
@ -120,53 +117,7 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endcache %}
</div> </div>
</div> </div>
</section> </section>
{% endblock content %} {% endblock content %}
{% block javascript %}
<script defer>
document.addEventListener('DOMContentLoaded', function() {
// Minimal JavaScript for toggling Featured Offers tabs
const featuredTabs = document.querySelectorAll('input[name="featured_tabs"]');
const featuredTabContents = document.querySelectorAll('#featured-tab-contents .tab-content');
function updateFeaturedTabs() {
featuredTabs.forEach(radio => {
if (radio.checked) {
const target = radio.id;
featuredTabContents.forEach(content => {
content.style.display = content.getAttribute('data-tab') === target ? 'block' : 'none';
});
}
});
}
featuredTabs.forEach(radio => {
radio.addEventListener('change', updateFeaturedTabs);
});
// Initialize tabs on page load
updateFeaturedTabs();
});
</script>
{% endblock %}
{% block css %}
<style>
.tabs-box .tab {
z-index: 1;
}
.tabs-box .tab:checked,
.tabs-box .tab.active {
z-index: 2;
background-color: var(--color-base-200);
accent-color: var(--color-base-200);
}
.tabs-box .tab:focus-visible {
outline: none;
}
</style>
{% endblock %}

View file

@ -1,19 +1,13 @@
{% load trade_offer_tags pagination_tags %} {% load trade_offer_tags pagination_tags %}
{% comment %}
This snippet renders a grid of trade offer cards (or acceptance cards) along with pagination controls.
For a TradeOffer, we use {% render_trade_offer %}; for a TradeAcceptance, {% render_trade_acceptance %}.
{% endcomment %}
<div class="flex flex-row gap-6 md:gap-2 lg:gap-6 flex-wrap justify-center items-start py-6"> <div class="flex flex-row gap-6 md:gap-2 lg:gap-6 flex-wrap justify-center py-6">
{% for offer in offers %} {% for offer in offers %}
<div class="flex flex-none">
{% if offer.accepted_by %} {% if offer.accepted_by %}
{# Render a trade acceptance using our new tag #} {# Render a trade acceptance using our new tag #}
{% render_trade_acceptance offer %} {% render_trade_acceptance offer %}
{% else %} {% else %}
{% render_trade_offer offer %} {% render_trade_offer offer %}
{% endif %} {% endif %}
</div>
{% empty %} {% empty %}
<div>No trade offers available.</div> <div>No trade offers available.</div>
{% endfor %} {% endfor %}

View file

@ -1,16 +0,0 @@
Hello {{ recipient_user }},
Great news! {{ acting_user }} ({{ acting_user_friend_code }}) has accepted your trade offer.
Trade Details:
- #{{ hash }}
- They are offering: {{ want_card }}
- They want: {{ has_card }}
What's next? You can now mark the trade as "Sent" once you've offered the card to them in the app, or reject the trade if needed.
Visit your dashboard to manage this trade:
{% url 'dashboard' %}
Happy trading!
PKMN Trade Club

View file

@ -1,16 +0,0 @@
Hello {{ recipient_user }},
{{ acting_user }} ({{ acting_user_friend_code }}) has marked your trade as "Received".
Trade Details:
- #{{ hash }}
- Card you sent: {{ has_card }}
- Card they offered: {{ want_card }}
What's next? Send a thank you to this user to increase their reputation!
Visit your dashboard to send thanks:
{% url 'dashboard' %}
Happy trading!
PKMN Trade Club

View file

@ -1,16 +0,0 @@
Hello {{ recipient_user }},
{{ acting_user }} ({{ acting_user_friend_code }}) has marked your trade as "Sent".
Trade Details:
- #{{ hash }}
- Card being sent to you: {{ has_card }}
- Card you're offering: {{ want_card }}
What's next? Once you respond to the trade in the app, please mark the trade as "Received" in your dashboard.
Visit your dashboard to manage this trade:
{% url 'dashboard' %}
Happy trading!
PKMN Trade Club

View file

@ -1,15 +0,0 @@
Hello {{ recipient_user }},
{{ acting_user }} ({{ acting_user_friend_code }}) has sent their thanks for the successful trade!
Trade Details:
- #{{ hash }}
- Card {% if is_initiator %}you{% else %}they{% endif %} sent: {{ has_card }}
- Card {% if is_initiator %}they{% else %}you{% endif %} offered: {{ want_card }}
This trade is now completed; no further actions can be made.
Thank you for using PKMN Trade Club.
Happy trading!
PKMN Trade Club

View file

@ -13,7 +13,7 @@
<span class="text-sm font-semibold text-center">Wants</span> <span class="text-sm font-semibold text-center">Wants</span>
</div> </div>
<div class="absolute inset-x-0 top-1/2 transform -translate-y-1/2 flex justify-center"> <div class="absolute inset-x-0 top-1/2 transform -translate-y-1/2 flex justify-center">
<div class="avatar tooltip tooltip-top" data-tip="{{ initiated_by_username }} | {{ initiated_reputation }}"> <div class="avatar tooltip tooltip-top" data-tip="{{ initiated_by_username }} | {{ initiated_reputation }} rep">
<div class="w-10 rounded-full"> <div class="w-10 rounded-full">
{{ initiated_by_email|gravatar:40 }} {{ initiated_by_email|gravatar:40 }}
</div> </div>
@ -73,7 +73,7 @@
<span class="text-sm font-semibold text-center">Wants</span> <span class="text-sm font-semibold text-center">Wants</span>
</div> </div>
<div class="absolute inset-x-0 top-1/2 transform -translate-y-1/2 flex justify-center"> <div class="absolute inset-x-0 top-1/2 transform -translate-y-1/2 flex justify-center">
<div class="avatar"> <div class="avatar tooltip tooltip-top" data-tip="{{ initiated_by_username }} | {{ initiated_reputation }} rep">
<div class="w-10 rounded-full"> <div class="w-10 rounded-full">
{{ initiated_by_email|gravatar:40 }} {{ initiated_by_email|gravatar:40 }}
</div> </div>

View file

@ -8,7 +8,10 @@ from datetime import timedelta
from django.utils import timezone from django.utils import timezone
import uuid import uuid
import hashlib import hashlib
from django.core.mail import send_mail
from django.conf import settings from django.conf import settings
from django.template.loader import render_to_string
from django.contrib.sites.models import Site
ACTIVE_STATES = [ ACTIVE_STATES = [
TradeAcceptance.AcceptanceState.ACCEPTED, TradeAcceptance.AcceptanceState.ACCEPTED,
@ -92,7 +95,6 @@ def trade_acceptance_post_delete(sender, instance, **kwargs):
def trade_acceptance_email_notification(sender, instance, created, **kwargs): def trade_acceptance_email_notification(sender, instance, created, **kwargs):
# Only proceed if the update was triggered by an acting user. # Only proceed if the update was triggered by an acting user.
if not hasattr(instance, "_actioning_user"): if not hasattr(instance, "_actioning_user"):
print("No actioning user")
return return
# check if were in debug mode # check if were in debug mode
@ -122,42 +124,41 @@ def trade_acceptance_email_notification(sender, instance, created, **kwargs):
else: else:
return return
print("state", state)
print("acting_user", acting_user)
# Determine the non-acting party: # Determine the non-acting party:
if instance.trade_offer.initiated_by == acting_user: if instance.trade_offer.initiated_by == acting_user:
# The initiator made the change; notify the acceptor. # The initiator made the change; notify the acceptor.
recipient_user = instance.accepted_by.user recipient_user = instance.accepted_by.user
email_template = "trades/email/trade_update_" + state + ".txt"
email_subject = "[PKMN Trade Club] Trade Update"
else: else:
# The acceptor made the change; notify the initiator. # The acceptor made the change; notify the initiator.
recipient_user = instance.trade_offer.initiated_by.user recipient_user = instance.trade_offer.initiated_by.user
email_template = "trades/email/trade_update_" + state + ".txt"
email_subject = "[PKMN Trade Club] Trade Update"
is_initiator = instance.trade_offer.initiated_by == acting_user is_initiator = instance.trade_offer.initiated_by == acting_user
from django.template.loader import render_to_string
email_context = { email_context = {
"has_card": instance.requested_card, "has_card": instance.requested_card,
"want_card": instance.offered_card, "want_card": instance.offered_card,
"hash": instance.hash, "hash": instance.hash,
"acting_user": acting_user.username, "acting_user": acting_user.username,
"acting_user_ign": instance.trade_offer.initiated_by.in_game_name if is_initiator else instance.accepted_by.in_game_name,
"recipient_user": recipient_user.username, "recipient_user": recipient_user.username,
"recipient_user_ign": instance.accepted_by.in_game_name if is_initiator else instance.trade_offer.initiated_by.in_game_name,
"acting_user_friend_code": instance.trade_offer.initiated_by.friend_code if is_initiator else instance.accepted_by.friend_code, "acting_user_friend_code": instance.trade_offer.initiated_by.friend_code if is_initiator else instance.accepted_by.friend_code,
"is_initiator": is_initiator, "is_initiator": is_initiator,
"domain": Site.objects.get_current().domain,
"pk": instance.pk, "pk": instance.pk,
} }
print("email_context", email_context) email_template = "email/trades/trade_update_" + state + ".txt"
email_subject = render_to_string("email/common/subject.txt", email_context)
email_subject += render_to_string("email/trades/trade_update_" + state + "_subject.txt", email_context)
email_body = render_to_string(email_template, email_context) email_body = render_to_string(email_template, email_context)
from django.core.mail import send_mail print("initiated by: ", instance.trade_offer.initiated_by, ", accepted by: ", instance.accepted_by, ", acting user: ", acting_user, ", recipient user: ", recipient_user, ", state: ", state)
send_mail( send_mail(
email_subject, email_subject,
email_body, email_body,
None, # Django will use DEFAULT_FROM_EMAIL from settings None,
[recipient_user.email], [recipient_user.email],
) )