diff --git a/src/app/ItemTradesPage.js b/src/app/ItemTradesPage.js
index 06ac2d3..a076080 100644
--- a/src/app/ItemTradesPage.js
+++ b/src/app/ItemTradesPage.js
@@ -29,7 +29,7 @@ export function ItemTradesOfferingPage() {
user {
id
username
- # lastUpdatedAnyTrade
+ lastTradeActivity
}
closetList {
id
@@ -58,7 +58,7 @@ export function ItemTradesSeekingPage() {
user {
id
username
- # lastUpdatedAnyTrade
+ lastTradeActivity
}
closetList {
id
@@ -155,7 +155,7 @@ function ItemTradesTable({
{/* A small wording tweak to fit better on the xsmall screens! */}
Last active
- Updated
+ Active at
Compare
@@ -181,6 +181,7 @@ function ItemTradesTable({
href={`/user/${trade.user.id}/items#list-${trade.closetList.id}`}
username={trade.user.username}
listName={trade.closetList.name}
+ lastTradeActivity={trade.user.lastTradeActivity}
/>
))}
{!loading && data.item.trades.length === 0 && (
@@ -199,7 +200,13 @@ function ItemTradesTable({
);
}
-function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
+function ItemTradesTableRow({
+ compareListHeading,
+ href,
+ username,
+ listName,
+ lastTradeActivity,
+}) {
const history = useHistory();
const onClick = React.useCallback(() => history.push(href), [history, href]);
const focusBackground = useColorModeValue("gray.100", "gray.600");
@@ -232,8 +239,10 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
{username}
- <1 week
- This week
+ {new Intl.DateTimeFormat("en", {
+ month: "short",
+ year: "numeric",
+ }).format(new Date(lastTradeActivity))}
+ (WIP: This is placeholder data!)
}
>
diff --git a/src/server/loaders.js b/src/server/loaders.js
index e2108af..57df5dc 100644
--- a/src/server/loaders.js
+++ b/src/server/loaders.js
@@ -919,6 +919,44 @@ const buildUserClosetListsLoader = (db, loaders) =>
);
});
+const buildUserLastTradeActivityLoader = (db) =>
+ new DataLoader(async (userIds) => {
+ const qs = userIds.map((_) => "?").join(",");
+ const [rows, _] = await db.execute(
+ `
+ SELECT
+ closet_hangers.user_id AS user_id,
+ MAX(closet_hangers.updated_at) AS last_trade_activity
+ FROM closet_hangers
+ INNER JOIN users ON users.id = closet_hangers.user_id
+ LEFT JOIN closet_lists ON closet_lists.id = closet_hangers.list_id
+ WHERE (
+ closet_hangers.user_id IN (${qs})
+ AND (
+ (closet_hangers.list_id IS NOT NULL AND closet_lists.visibility >= 2)
+ OR (
+ closet_hangers.list_id IS NULL AND closet_hangers.owned = 1
+ AND users.owned_closet_hangers_visibility >= 2
+ )
+ OR (
+ closet_hangers.list_id IS NULL AND closet_hangers.owned = 0
+ AND users.wanted_closet_hangers_visibility >= 2
+ )
+ )
+ )
+ GROUP BY closet_hangers.user_id
+ `,
+ userIds
+ );
+
+ const entities = rows.map(normalizeRow);
+
+ return userIds.map((userId) => {
+ const entity = entities.find((e) => e.userId === String(userId));
+ return entity ? entity.lastTradeActivity : null;
+ });
+ });
+
const buildZoneLoader = (db) => {
const zoneLoader = new DataLoader(async (ids) => {
const qs = ids.map((_) => "?").join(",");
@@ -1022,6 +1060,7 @@ function buildLoaders(db) {
loaders.userByEmailLoader = buildUserByEmailLoader(db);
loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
loaders.userClosetListsLoader = buildUserClosetListsLoader(db, loaders);
+ loaders.userLastTradeActivityLoader = buildUserLastTradeActivityLoader(db);
loaders.zoneLoader = buildZoneLoader(db);
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
diff --git a/src/server/types/User.js b/src/server/types/User.js
index 14af26c..5c521a3 100644
--- a/src/server/types/User.js
+++ b/src/server/types/User.js
@@ -10,6 +10,10 @@ const typeDefs = gql`
itemsTheyOwn: [Item!]!
itemsTheyWant: [Item!]!
+
+ # When this user last updated any of their trade lists, as an ISO 8601
+ # timestamp.
+ lastTradeActivity: String!
}
extend type Query {
@@ -166,6 +170,11 @@ const resolvers = {
return closetListNodes;
},
+
+ lastTradeActivity: async ({ id }, _, { userLastTradeActivityLoader }) => {
+ const lastTradeActivity = await userLastTradeActivityLoader.load(id);
+ return lastTradeActivity.toISOString();
+ },
},
Query: {