Skip to content

Commit 863c825

Browse files
authored
Merge pull request #20 from MichaelBitard/main
add franceconnect-particulier to franceConnect button
2 parents e2e35e2 + 9f9c047 commit 863c825

File tree

3 files changed

+124
-47
lines changed

3 files changed

+124
-47
lines changed

src/login/pages/Login.stories.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,33 @@ export const WithFranceConnectAndProConnectProviders: Story = {
138138
)
139139
};
140140

141+
export const WithFranceConnectNotOnFirstPosition: Story = {
142+
render: () => (
143+
<KcPageStory
144+
kcContext={{
145+
social: {
146+
displayInfo: true,
147+
providers: [
148+
{
149+
loginUrl: "proConnect",
150+
alias: "Pro Connect",
151+
providerId: "agentconnect", // NOTE: It is still agentconnect, pro connect is a rebrand of agentconnect.
152+
displayName: "Pro Connect",
153+
iconClasses: ""
154+
},{
155+
loginUrl: "france-connect",
156+
alias: "france-connect",
157+
providerId: "franceconnect",
158+
displayName: "France Connect",
159+
iconClasses: ""
160+
},
161+
]
162+
}
163+
}}
164+
/>
165+
)
166+
};
167+
141168
export const WithGitHub: Story = {
142169
render: () => (
143170
<KcPageStory

src/login/pages/Login.tsx

Lines changed: 76 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import type { PageProps } from "keycloakify/login/pages/PageProps";
99
import { useState } from "react";
1010
import type { KcContext } from "../KcContext";
1111
import type { I18n } from "../i18n";
12-
12+
import "./login.css";
13+
const franceConnectProviderIds = ["franceconnect", "franceconnect-particulier"];
1314
export default function Login(props: PageProps<Extract<KcContext, { pageId: "login.ftl" }>, I18n>) {
1415
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
1516

@@ -23,7 +24,7 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
2324
const { msg, msgStr } = i18n;
2425

2526
const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
26-
27+
2728
return (
2829
<Template
2930
kcContext={kcContext}
@@ -50,60 +51,88 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
5051
{realm.password && social?.providers !== undefined && social.providers.length !== 0 && (
5152
<div id="kc-social-providers" className={kcClsx("kcFormSocialAccountSectionClass")}>
5253
<hr />
53-
<ul>
54-
{social.providers.map((...[p]) => {
55-
if (p.providerId === "agentconnect" || p.providerId === "proconnect") {
56-
return <ProConnectButton key={p.alias} style={{ textAlign: "center" }} url={p.loginUrl} />;
57-
}
54+
<div>
55+
{social.providers
56+
.map((p, index) => {
57+
if (p.providerId === "agentconnect" || p.providerId === "proconnect") {
58+
return <ProConnectButton key={p.alias} style={{ textAlign: "center" }} url={p.loginUrl} />;
59+
}
5860

59-
if (p.providerId === "franceconnect") {
60-
return <FranceConnectButton key={p.alias} style={{ textAlign: "center" }} url={p.loginUrl} />;
61-
}
61+
if (franceConnectProviderIds.includes(p.providerId)) {
62+
if (index !== 0) {
63+
throw new Error('Le bouton FranceConnect doit être le premier bouton de connexion');
64+
}
65+
return (
66+
<>
67+
<p className={fr.cx("fr-text--light")}>
68+
FranceConnect est la solution proposée par l’État pour sécuriser et simplifier la connexion à
69+
vos services en ligne.
70+
</p>
71+
<FranceConnectButton key={p.alias} style={{ textAlign: "center" }} url={p.loginUrl} />
72+
</>
73+
);
74+
}
6275

63-
return (
64-
<Button
65-
className={fr.cx("fr-m-1w")}
66-
key={p.alias}
67-
iconId={(() => {
68-
switch (p.providerId) {
69-
case "github":
70-
return "ri-github-fill";
71-
case "google":
72-
return "ri-google-fill";
73-
case "facebook":
74-
return "ri-facebook-fill";
75-
case "microsoft":
76-
return "ri-microsoft-fill";
77-
case "twitter":
78-
return "ri-twitter-fill";
79-
case "instagram":
80-
return "ri-instagram-fill";
81-
case "linkedin":
82-
return "ri-linkedin-fill";
83-
case "stackoverflow":
84-
return "ri-stack-overflow-fill";
85-
case "gitlab":
86-
return "ri-gitlab-fill";
87-
}
88-
return "ri-external-link-line";
89-
})()}
90-
linkProps={{
91-
href: p.loginUrl
92-
}}
93-
>
94-
{p.displayName}
95-
</Button>
96-
);
97-
})}
98-
</ul>
76+
return (
77+
<div style={{
78+
display: 'flex',
79+
justifyContent: 'center'
80+
}}>
81+
<Button
82+
className={fr.cx("fr-m-1w")}
83+
key={p.alias}
84+
iconId={(() => {
85+
switch (p.providerId) {
86+
case "github":
87+
return "ri-github-fill";
88+
case "google":
89+
return "ri-google-fill";
90+
case "facebook":
91+
return "ri-facebook-fill";
92+
case "microsoft":
93+
return "ri-microsoft-fill";
94+
case "twitter":
95+
return "ri-twitter-fill";
96+
case "instagram":
97+
return "ri-instagram-fill";
98+
case "linkedin":
99+
return "ri-linkedin-fill";
100+
case "stackoverflow":
101+
return "ri-stack-overflow-fill";
102+
case "gitlab":
103+
return "ri-gitlab-fill";
104+
}
105+
return "ri-external-link-line";
106+
})()}
107+
linkProps={{
108+
href: p.loginUrl
109+
}}
110+
>
111+
{p.displayName}
112+
</Button>
113+
</div>
114+
);
115+
})
116+
.map((value, index) => {
117+
if (index >= 1 && franceConnectProviderIds.includes(social.providers?.[0].providerId ?? '')) {
118+
return (
119+
<>
120+
<div className="separator">OU</div>
121+
{value}
122+
</>
123+
);
124+
}
125+
return value;
126+
})}
127+
</div>
99128
</div>
100129
)}
101130
</>
102131
}
103132
>
104133
<div id="kc-form">
105134
<div id="kc-form-wrapper">
106-
{social?.providers !== undefined && social.providers.length !== 0 && <h2>{msg("or-login-with-email")}</h2>}
135+
{social?.providers !== undefined && social.providers.length !== 0 && <h2>{msg("or-login-with-email")}</h2>}
107136
{realm.password && (
108137
<form
109138
id="kc-form-login"

src/login/pages/login.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.separator {
2+
display: flex;
3+
align-items: center;
4+
text-align: center;
5+
margin-bottom: 1rem;
6+
}
7+
8+
.separator::before,
9+
.separator::after {
10+
content: "";
11+
flex: 1;
12+
border-bottom: 1px solid var(--border-default-grey);
13+
}
14+
15+
.separator:not(:empty)::before {
16+
margin-right: 0.5em;
17+
}
18+
19+
.separator:not(:empty)::after {
20+
margin-left: 0.5em;
21+
}

0 commit comments

Comments
 (0)