add real timestamp to trades page
This commit is contained in:
parent
d275c96396
commit
c23243fcb7
3 changed files with 64 additions and 6 deletions
|
@ -29,7 +29,7 @@ export function ItemTradesOfferingPage() {
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
username
|
username
|
||||||
# lastUpdatedAnyTrade
|
lastTradeActivity
|
||||||
}
|
}
|
||||||
closetList {
|
closetList {
|
||||||
id
|
id
|
||||||
|
@ -58,7 +58,7 @@ export function ItemTradesSeekingPage() {
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
username
|
username
|
||||||
# lastUpdatedAnyTrade
|
lastTradeActivity
|
||||||
}
|
}
|
||||||
closetList {
|
closetList {
|
||||||
id
|
id
|
||||||
|
@ -155,7 +155,7 @@ function ItemTradesTable({
|
||||||
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
|
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
|
||||||
{/* A small wording tweak to fit better on the xsmall screens! */}
|
{/* A small wording tweak to fit better on the xsmall screens! */}
|
||||||
<Box display={{ base: "none", sm: "block" }}>Last active</Box>
|
<Box display={{ base: "none", sm: "block" }}>Last active</Box>
|
||||||
<Box display={{ base: "block", sm: "none" }}>Updated</Box>
|
<Box display={{ base: "block", sm: "none" }}>Active at</Box>
|
||||||
</ItemTradesTableCell>
|
</ItemTradesTableCell>
|
||||||
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
|
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
|
||||||
Compare
|
Compare
|
||||||
|
@ -181,6 +181,7 @@ function ItemTradesTable({
|
||||||
href={`/user/${trade.user.id}/items#list-${trade.closetList.id}`}
|
href={`/user/${trade.user.id}/items#list-${trade.closetList.id}`}
|
||||||
username={trade.user.username}
|
username={trade.user.username}
|
||||||
listName={trade.closetList.name}
|
listName={trade.closetList.name}
|
||||||
|
lastTradeActivity={trade.user.lastTradeActivity}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{!loading && data.item.trades.length === 0 && (
|
{!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 history = useHistory();
|
||||||
const onClick = React.useCallback(() => history.push(href), [history, href]);
|
const onClick = React.useCallback(() => history.push(href), [history, href]);
|
||||||
const focusBackground = useColorModeValue("gray.100", "gray.600");
|
const focusBackground = useColorModeValue("gray.100", "gray.600");
|
||||||
|
@ -232,8 +239,10 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
|
||||||
{username}
|
{username}
|
||||||
</ItemTradesTableCell>
|
</ItemTradesTableCell>
|
||||||
<ItemTradesTableCell fontSize="xs">
|
<ItemTradesTableCell fontSize="xs">
|
||||||
<Box display={{ base: "block", sm: "none" }}><1 week</Box>
|
{new Intl.DateTimeFormat("en", {
|
||||||
<Box display={{ base: "none", sm: "block" }}>This week</Box>
|
month: "short",
|
||||||
|
year: "numeric",
|
||||||
|
}).format(new Date(lastTradeActivity))}
|
||||||
</ItemTradesTableCell>
|
</ItemTradesTableCell>
|
||||||
<ItemTradesTableCell fontSize="xs">
|
<ItemTradesTableCell fontSize="xs">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -249,6 +258,7 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
|
||||||
Constellation Dress
|
Constellation Dress
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box>(WIP: This is placeholder data!)</Box>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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 buildZoneLoader = (db) => {
|
||||||
const zoneLoader = new DataLoader(async (ids) => {
|
const zoneLoader = new DataLoader(async (ids) => {
|
||||||
const qs = ids.map((_) => "?").join(",");
|
const qs = ids.map((_) => "?").join(",");
|
||||||
|
@ -1022,6 +1060,7 @@ function buildLoaders(db) {
|
||||||
loaders.userByEmailLoader = buildUserByEmailLoader(db);
|
loaders.userByEmailLoader = buildUserByEmailLoader(db);
|
||||||
loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
|
loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
|
||||||
loaders.userClosetListsLoader = buildUserClosetListsLoader(db, loaders);
|
loaders.userClosetListsLoader = buildUserClosetListsLoader(db, loaders);
|
||||||
|
loaders.userLastTradeActivityLoader = buildUserLastTradeActivityLoader(db);
|
||||||
loaders.zoneLoader = buildZoneLoader(db);
|
loaders.zoneLoader = buildZoneLoader(db);
|
||||||
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
|
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@ const typeDefs = gql`
|
||||||
|
|
||||||
itemsTheyOwn: [Item!]!
|
itemsTheyOwn: [Item!]!
|
||||||
itemsTheyWant: [Item!]!
|
itemsTheyWant: [Item!]!
|
||||||
|
|
||||||
|
# When this user last updated any of their trade lists, as an ISO 8601
|
||||||
|
# timestamp.
|
||||||
|
lastTradeActivity: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
extend type Query {
|
extend type Query {
|
||||||
|
@ -166,6 +170,11 @@ const resolvers = {
|
||||||
|
|
||||||
return closetListNodes;
|
return closetListNodes;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
lastTradeActivity: async ({ id }, _, { userLastTradeActivityLoader }) => {
|
||||||
|
const lastTradeActivity = await userLastTradeActivityLoader.load(id);
|
||||||
|
return lastTradeActivity.toISOString();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Query: {
|
Query: {
|
||||||
|
|
Loading…
Reference in a new issue