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 {
|
||||
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({
|
|||
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
|
||||
{/* A small wording tweak to fit better on the xsmall screens! */}
|
||||
<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 as="th" width={{ base: "23%", md: "18ex" }}>
|
||||
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}
|
||||
</ItemTradesTableCell>
|
||||
<ItemTradesTableCell fontSize="xs">
|
||||
<Box display={{ base: "block", sm: "none" }}><1 week</Box>
|
||||
<Box display={{ base: "none", sm: "block" }}>This week</Box>
|
||||
{new Intl.DateTimeFormat("en", {
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
}).format(new Date(lastTradeActivity))}
|
||||
</ItemTradesTableCell>
|
||||
<ItemTradesTableCell fontSize="xs">
|
||||
<Tooltip
|
||||
|
@ -249,6 +258,7 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
|
|||
Constellation Dress
|
||||
</Box>
|
||||
</Box>
|
||||
<Box>(WIP: This is placeholder data!)</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 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);
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in a new issue