Disable org link when user is deactivated

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-18 16:59:52 +04:00
parent ab5fe8e5e2
commit 13aef29ddf
4 changed files with 90 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f6caf8d14eaaea74987cd5f91fedaed3>> * @generated SignedSource<<889efcfe178bb170887494345d05c48b>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,12 +9,16 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type ProfileState = "ACTIVE" | "INACTIVE";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type MembershipCardFragment$data = { export type MembershipCardFragment$data = {
readonly lastSession: { readonly membership: {
readonly expiresAt: string; readonly lastSession: {
readonly id: string; readonly expiresAt: string;
} | null | undefined; readonly id: string;
} | null | undefined;
};
readonly state: ProfileState;
readonly " $fragmentType": "MembershipCardFragment"; readonly " $fragmentType": "MembershipCardFragment";
}; };
export type MembershipCardFragment$key = { export type MembershipCardFragment$key = {
@@ -31,33 +35,55 @@ const node: ReaderFragment = {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Session", "kind": "ScalarField",
"kind": "LinkedField", "name": "state",
"name": "lastSession",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "expiresAt",
"storageKey": null
}
],
"storageKey": null "storageKey": null
},
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "membership",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Session",
"kind": "LinkedField",
"name": "lastSession",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "expiresAt",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
},
"action": "THROW"
} }
], ],
"type": "Membership", "type": "Profile",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = "3da5f340850d352daaa553ca7b78aa37"; (node as any).hash = "2e4f6ddee75ca32542f959c44de58e25";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<68acd1fa60fc1efe40e3983441ae01da>> * @generated SignedSource<<0e09a0566214f0c5c5ee2919d75bb85a>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -17,13 +17,11 @@ export type MembershipsPageQuery$data = {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly id: string; readonly id: string;
readonly membership: {
readonly " $fragmentSpreads": FragmentRefs<"MembershipCardFragment">;
};
readonly organization: { readonly organization: {
readonly name: string; readonly name: string;
readonly " $fragmentSpreads": FragmentRefs<"MembershipCard_organizationFragment">; readonly " $fragmentSpreads": FragmentRefs<"MembershipCard_organizationFragment">;
}; };
readonly " $fragmentSpreads": FragmentRefs<"MembershipCardFragment">;
}; };
}>; }>;
}; };
@@ -153,24 +151,9 @@ return {
"selections": [ "selections": [
(v1/*: any*/), (v1/*: any*/),
{ {
"kind": "RequiredField", "args": null,
"field": { "kind": "FragmentSpread",
"alias": null, "name": "MembershipCardFragment"
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "membership",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "MembershipCardFragment"
}
],
"storageKey": null
},
"action": "THROW"
}, },
{ {
"kind": "RequiredField", "kind": "RequiredField",
@@ -257,6 +240,13 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v1/*: any*/), (v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -338,7 +328,7 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "d3ee4e9e305c7a2f57179cf540f4cd6c", "cacheID": "d10df01cc523419b3f998a26d3ecbf7b",
"id": null, "id": null,
"metadata": { "metadata": {
"connection": [ "connection": [
@@ -355,11 +345,11 @@ return {
}, },
"name": "MembershipsPageQuery", "name": "MembershipsPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query MembershipsPageQuery {\n viewer {\n profiles(first: 1000, orderBy: {direction: ASC, field: ORGANIZATION_NAME}) {\n edges {\n node {\n id\n membership {\n ...MembershipCardFragment\n id\n }\n organization {\n name\n ...MembershipCard_organizationFragment\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n }\n}\n\nfragment MembershipCardFragment on Membership {\n lastSession {\n id\n expiresAt\n }\n}\n\nfragment MembershipCard_organizationFragment on Organization {\n id\n name\n logoUrl\n}\n" "text": "query MembershipsPageQuery {\n viewer {\n profiles(first: 1000, orderBy: {direction: ASC, field: ORGANIZATION_NAME}) {\n edges {\n node {\n id\n ...MembershipCardFragment\n organization {\n name\n ...MembershipCard_organizationFragment\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n }\n}\n\nfragment MembershipCardFragment on Profile {\n state\n membership {\n lastSession {\n id\n expiresAt\n }\n id\n }\n}\n\nfragment MembershipCard_organizationFragment on Organization {\n id\n name\n logoUrl\n}\n"
} }
}; };
})(); })();
(node as any).hash = "c87fe091011b4d5e5bffe0309eb4211f"; (node as any).hash = "578d6a9573ba32c7b017ec0bae079651";
export default node; export default node;

View File

@@ -26,9 +26,7 @@ export const membershipsPageQuery = graphql`
edges @required(action: THROW) { edges @required(action: THROW) {
node { node {
id id
membership @required(action: THROW) {
...MembershipCardFragment ...MembershipCardFragment
}
organization @required(action: THROW) { organization @required(action: THROW) {
name name
...MembershipCard_organizationFragment ...MembershipCard_organizationFragment
@@ -94,7 +92,7 @@ export function MembershipsPage(props: {
profiles.map(({ node }) => ( profiles.map(({ node }) => (
<MembershipCard <MembershipCard
key={node.id} key={node.id}
fKey={node.membership} fKey={node}
organizationFragmentRef={node.organization} organizationFragmentRef={node.organization}
/> />
)) ))

View File

@@ -17,10 +17,13 @@ import type { MembershipCard_organizationFragment$key } from "#/__generated__/ia
import type { MembershipCardFragment$key } from "#/__generated__/iam/MembershipCardFragment.graphql"; import type { MembershipCardFragment$key } from "#/__generated__/iam/MembershipCardFragment.graphql";
const fragment = graphql` const fragment = graphql`
fragment MembershipCardFragment on Membership { fragment MembershipCardFragment on Profile {
lastSession { state
id membership @required(action: THROW) {
expiresAt lastSession {
id
expiresAt
}
} }
} }
`; `;
@@ -42,7 +45,7 @@ export function MembershipCard(props: MembershipCardProps) {
const { fKey, organizationFragmentRef } = props; const { fKey, organizationFragmentRef } = props;
const { __ } = useTranslate(); const { __ } = useTranslate();
const { lastSession } = useFragment<MembershipCardFragment$key>( const { membership, ...user } = useFragment<MembershipCardFragment$key>(
fragment, fragment,
fKey, fKey,
); );
@@ -51,8 +54,8 @@ export function MembershipCard(props: MembershipCardProps) {
organizationFragmentRef, organizationFragmentRef,
); );
const isExpired const isExpired
= lastSession && parseDate(lastSession.expiresAt) < new Date(); = membership.lastSession && parseDate(membership.lastSession.expiresAt) < new Date();
const isAssuming = !!lastSession && !isExpired; const isAssuming = !!membership.lastSession && !isExpired;
const getAuthBadge = () => { const getAuthBadge = () => {
if (isAssuming) { if (isAssuming) {
@@ -94,11 +97,17 @@ export function MembershipCard(props: MembershipCardProps) {
</div> </div>
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Link to={`/organizations/${organization.id}`}> {user.state === "ACTIVE"
{isAssuming ? (
? <Button variant="secondary">{__("Start")}</Button> <Link to={`/organizations/${organization.id}`}>
: <Button>{__("Login")}</Button>} {isAssuming
</Link> ? <Button variant="secondary">{__("Start")}</Button>
: <Button>{__("Login")}</Button>}
</Link>
)
: (
<Button variant="secondary" disabled>{__("Account deactivated")}</Button>
)}
</div> </div>
</div> </div>
</Card> </Card>