diff --git a/app/components/play/GroupCard.tsx b/app/components/play/GroupCard.tsx index 04d6c2e54..9f1af68f7 100644 --- a/app/components/play/GroupCard.tsx +++ b/app/components/play/GroupCard.tsx @@ -1,3 +1,4 @@ +import clsx from "clsx"; import { Form } from "remix"; import { Avatar } from "~/components/Avatar"; import { Button } from "~/components/Button"; @@ -10,14 +11,16 @@ export function GroupCard({ group, isCaptain = false, type, + ranked, }: { group: LookingLoaderDataGroup; isCaptain?: boolean; type?: "LIKES_GIVEN" | "NEUTRAL" | "LIKES_RECEIVED"; + ranked?: boolean; }) { const buttonText = () => { if (type === "LIKES_GIVEN") return "Undo"; - if (type === "NEUTRAL") return "Let's play!"; + if (type === "NEUTRAL") return "Let's play?"; return "Group up"; }; @@ -25,12 +28,17 @@ export function GroupCard({ if (type === "LIKES_GIVEN") return "UNLIKE"; if (type === "NEUTRAL") return "LIKE"; - return "UNITE_GROUP"; + return "UNITE_GROUPS"; }; return (
+ {typeof ranked === "boolean" && ( +
+ {ranked ? "Ranked" : "Unranked"} +
+ )}
{group.members?.map((member) => { return ( diff --git a/app/models/LFGGroup.server.ts b/app/models/LFGGroup.server.ts index 3658c25fb..4c45ba44d 100644 --- a/app/models/LFGGroup.server.ts +++ b/app/models/LFGGroup.server.ts @@ -63,13 +63,15 @@ export interface UniteGroupsArgs { survivingGroupId: string; otherGroupId: string; removeCaptainsFromOther: boolean; + unitedGroupIsRanked?: boolean; } export function uniteGroups({ survivingGroupId, otherGroupId, removeCaptainsFromOther, + unitedGroupIsRanked, }: UniteGroupsArgs) { - return db.$transaction([ + const queries = [ db.lfgGroupMember.updateMany({ where: { groupId: otherGroupId }, data: { @@ -84,7 +86,18 @@ export function uniteGroups({ OR: [{ likerId: survivingGroupId }, { targetId: survivingGroupId }], }, }), - ]); + ]; + + if (typeof unitedGroupIsRanked === "boolean") { + queries.push( + db.lfgGroup.update({ + where: { id: survivingGroupId }, + data: { ranked: unitedGroupIsRanked }, + }) + ); + } + + return db.$transaction(queries); } export function findById(id: string) { diff --git a/app/routes/play/looking.tsx b/app/routes/play/looking.tsx index 194596714..535230dfd 100644 --- a/app/routes/play/looking.tsx +++ b/app/routes/play/looking.tsx @@ -30,7 +30,7 @@ const lookingActionSchema = z.union([ targetGroupId: z.string().uuid(), }), z.object({ - _action: z.literal("UNITE_GROUP"), + _action: z.literal("UNITE_GROUPS"), targetGroupId: z.string().uuid(), // we also get target number size so that when you like or try to unite groups // what you see on your screen will be guaranteed to match what the group @@ -55,7 +55,7 @@ export const action: ActionFunction = async ({ request, context }) => { validate(isGroupAdmin({ group: ownGroup, user }), "Not group admin"); switch (data._action) { - case "UNITE_GROUP": { + case "UNITE_GROUPS": { validate( canUniteWithGroup({ ownGroupType: ownGroup.type, @@ -76,8 +76,8 @@ export const action: ActionFunction = async ({ request, context }) => { break; } - await LFGGroup.uniteGroups( - uniteGroupInfo( + await LFGGroup.uniteGroups({ + ...uniteGroupInfo( { id: ownGroup.id, memberCount: ownGroup.members.length, @@ -86,8 +86,16 @@ export const action: ActionFunction = async ({ request, context }) => { id: groupToUniteWith.id, memberCount: groupToUniteWith.members.length, } - ) - ); + ), + unitedGroupIsRanked: + // if one group is ranked and other is unranked + // the new group should use the ranked status of the + // target group + ownGroup.ranked === groupToUniteWith.ranked || + typeof groupToUniteWith.ranked !== "boolean" + ? undefined + : groupToUniteWith.ranked, + }); break; } @@ -134,6 +142,7 @@ export type LookingLoaderDataGroup = { discordName: string; discordDiscriminator: string; }[]; + ranked?: boolean; }; interface LookingLoaderData { @@ -171,6 +180,7 @@ export const loader: LoaderFunction = async ({ context }) => { const ownGroupForResponse: LookingLoaderDataGroup = { id: ownGroup.id, members: ownGroupWithMembers.members.map((m) => m.user), + ranked: ownGroup.ranked ?? undefined, }; return json({ @@ -194,6 +204,7 @@ export const loader: LoaderFunction = async ({ context }) => { group.ranked && lookingForMatch ? undefined : group.members.map((m) => m.user), + ranked: group.ranked ?? undefined, })) .reduce( ( @@ -251,7 +262,7 @@ export default function LookingPage() { return (
- +
@@ -264,6 +275,7 @@ export default function LookingPage() { group={group} isCaptain={data.userIsCaptain} type="LIKES_GIVEN" + ranked={group.ranked} /> ); })} @@ -279,6 +291,7 @@ export default function LookingPage() { group={group} isCaptain={data.userIsCaptain} type="NEUTRAL" + ranked={group.ranked} /> ); })} @@ -294,6 +307,7 @@ export default function LookingPage() { group={group} isCaptain={data.userIsCaptain} type="LIKES_RECEIVED" + ranked={data.ownGroup.ranked} /> ); })} diff --git a/app/styles/play-looking.css b/app/styles/play-looking.css index c67706ac0..988fd14f5 100644 --- a/app/styles/play-looking.css +++ b/app/styles/play-looking.css @@ -29,7 +29,8 @@ .play-looking__cards { display: flex; flex-direction: column; - gap: var(--s-3); + gap: var(--s-5); + margin-block-start: var(--s-4); } .play-looking__column-header { @@ -44,18 +45,35 @@ margin: 0 auto; background-color: var(--bg-lighter); border-radius: var(--rounded); - gap: var(--s-4); max-inline-size: 24rem; - padding-block: var(--s-3); + padding-block-end: var(--s-3); + padding-block-start: var(--s-2); padding-inline: var(--s-2); } +.play-looking__ranked-text { + background-color: var(--bg-lighter); + border-radius: var(--rounded); + color: var(--theme-secondary); + font-size: var(--fonts-xxs); + font-weight: var(--semi-bold); + margin-block-start: -17px; + padding-block: var(--s-0-5); + padding-inline: var(--s-2); +} + +.play-looking__ranked-text.ranked { + color: var(--theme); +} + .play-looking__card__members { display: flex; width: 100%; flex-wrap: wrap; justify-content: center; gap: var(--s-2); + margin-block-end: var(--s-3); + margin-block-start: var(--s-1-5); } .play-looking__member-card {