refactor(auth): use icon library for provider icons
This commit is contained in:
+3
-2
@@ -29,6 +29,7 @@
|
||||
"pino": "^10.3.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-icons": "^5.6.0",
|
||||
"stripe": "^22.2.1",
|
||||
"unstorage": "^1.17.5",
|
||||
"xstate": "^5",
|
||||
@@ -36,8 +37,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@serwist/turbopack": "^9.0.0",
|
||||
"esbuild": "^0.25.0",
|
||||
"serwist": "^9.0.0",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
@@ -45,9 +44,11 @@
|
||||
"@vitest/coverage-v8": "^4.1.8",
|
||||
"@vitest/ui": "^4.1.8",
|
||||
"barrelsby": "^2.8.1",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.2.7",
|
||||
"jsdom": "^29.1.1",
|
||||
"serwist": "^9.0.0",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5",
|
||||
"vitest": "^4.1.8"
|
||||
|
||||
Generated
+12
@@ -47,6 +47,9 @@ importers:
|
||||
react-dom:
|
||||
specifier: 19.2.4
|
||||
version: 19.2.4(react@19.2.4)
|
||||
react-icons:
|
||||
specifier: ^5.6.0
|
||||
version: 5.6.0(react@19.2.4)
|
||||
stripe:
|
||||
specifier: ^22.2.1
|
||||
version: 22.2.1(@types/node@20.19.41)
|
||||
@@ -2698,6 +2701,11 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^19.2.4
|
||||
|
||||
react-icons@5.6.0:
|
||||
resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
@@ -5890,6 +5898,10 @@ snapshots:
|
||||
react: 19.2.4
|
||||
scheduler: 0.27.0
|
||||
|
||||
react-icons@5.6.0(react@19.2.4):
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react@19.2.4: {}
|
||||
|
||||
@@ -21,6 +21,7 @@ import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
|
||||
import { AuthErrorMessage } from "./auth-error-message";
|
||||
import { AuthLegalText } from "./auth-legal-text";
|
||||
import { AuthOtherOptionsDialog } from "./auth-other-options-dialog";
|
||||
import { AuthProviderIcon } from "./auth-provider-icon";
|
||||
import styles from "./auth-facebook-panel.module.css";
|
||||
|
||||
export interface AuthFacebookPanelProps {
|
||||
@@ -70,9 +71,7 @@ export function AuthFacebookPanel({ onSwitchToEmail }: AuthFacebookPanelProps) {
|
||||
<span className={styles.spinner} aria-hidden="true" />
|
||||
) : (
|
||||
<span className={styles.facebookIcon} aria-hidden="true">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="#1877f2">
|
||||
<path d="M13 22v-8h3l1-4h-4V7.5c0-1.2.4-2 2-2h2V2.2C16.6 2.1 15.5 2 14.3 2 11.5 2 9.5 3.7 9.5 7v3h-3v4h3v8h3.5z" />
|
||||
</svg>
|
||||
<AuthProviderIcon provider="facebook" />
|
||||
</span>
|
||||
)}
|
||||
<span className={styles.facebookLabel}>
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
* - Cancel 文本按钮
|
||||
*/
|
||||
import type { ReactNode } from "react";
|
||||
import { Mail } from "lucide-react";
|
||||
|
||||
import { BottomSheet } from "@/app/_components/core/bottom-sheet";
|
||||
|
||||
import { AuthProviderIcon } from "./auth-provider-icon";
|
||||
import { AuthSocialButton } from "./auth-social-button";
|
||||
import styles from "./auth-other-options-dialog.module.css";
|
||||
|
||||
@@ -53,17 +55,7 @@ export function AuthOtherOptionsDialog({
|
||||
|
||||
{mode === "facebook" ? (
|
||||
<AuthSocialButton
|
||||
icon={
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z" />
|
||||
</svg>
|
||||
}
|
||||
icon={<Mail size={20} aria-hidden="true" />}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onEmail();
|
||||
@@ -73,17 +65,7 @@ export function AuthOtherOptionsDialog({
|
||||
</AuthSocialButton>
|
||||
) : (
|
||||
<AuthSocialButton
|
||||
icon={
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="var(--color-facebook-blue)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M13 22v-8h3l1-4h-4V7.5c0-1.2.4-2 2-2h2V2.2C16.6 2.1 15.5 2 14.3 2 11.5 2 9.5 3.7 9.5 7v3h-3v4h3v8h3.5z" />
|
||||
</svg>
|
||||
}
|
||||
icon={<AuthProviderIcon provider="facebook" />}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onFacebook();
|
||||
@@ -97,26 +79,7 @@ export function AuthOtherOptionsDialog({
|
||||
<div className={styles.googleSlot}>{googleSlot}</div>
|
||||
) : (
|
||||
<AuthSocialButton
|
||||
icon={
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path
|
||||
d="M22 12.2c0-.7-.1-1.4-.2-2H12v3.8h5.6c-.2 1.3-1 2.4-2 3.1v2.6h3.2c1.9-1.7 2.9-4.2 2.9-7.5z"
|
||||
fill="#4285F4"
|
||||
/>
|
||||
<path
|
||||
d="M12 22c2.7 0 4.9-.9 6.5-2.4l-3.2-2.5c-.9.6-2 1-3.3 1-2.6 0-4.7-1.7-5.5-4.1H3.2v2.5C4.8 19.7 8.1 22 12 22z"
|
||||
fill="#34A853"
|
||||
/>
|
||||
<path
|
||||
d="M6.5 14a6 6 0 010-3.9V7.5H3.2a10 10 0 000 9l3.3-2.5z"
|
||||
fill="#FBBC05"
|
||||
/>
|
||||
<path
|
||||
d="M12 5.9c1.5 0 2.8.5 3.8 1.5l2.9-2.9C16.9 2.9 14.7 2 12 2 8.1 2 4.8 4.3 3.2 7.5L6.5 10c.8-2.4 2.9-4.1 5.5-4.1z"
|
||||
fill="#EA4335"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
icon={<AuthProviderIcon provider="google" />}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onGoogle();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* 认证面板:顶层 switch(Facebook / Email)+ 悬浮返回按钮
|
||||
*/
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
|
||||
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
|
||||
|
||||
@@ -36,19 +37,7 @@ export function AuthPanel() {
|
||||
onClick={handleBack}
|
||||
aria-label="Back"
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M15 18l-6-6 6-6" />
|
||||
</svg>
|
||||
<ChevronLeft size={20} strokeWidth={2.5} aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
{state.authPanelMode === "facebook" ? (
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import { FaApple, FaFacebookF } from "react-icons/fa6";
|
||||
import { FcGoogle } from "react-icons/fc";
|
||||
|
||||
export type AuthProviderIconName = "facebook" | "google" | "apple";
|
||||
|
||||
export interface AuthProviderIconProps {
|
||||
provider: AuthProviderIconName;
|
||||
size?: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function AuthProviderIcon({
|
||||
provider,
|
||||
size = 20,
|
||||
className,
|
||||
}: AuthProviderIconProps) {
|
||||
if (provider === "google") {
|
||||
return <FcGoogle size={size} className={className} aria-hidden="true" />;
|
||||
}
|
||||
|
||||
if (provider === "apple") {
|
||||
return <FaApple size={size} className={className} aria-hidden="true" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<FaFacebookF
|
||||
size={size}
|
||||
className={className}
|
||||
color="var(--color-facebook-blue)"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
import { type ReactNode } from "react";
|
||||
|
||||
import { AuthProviderIcon } from "./auth-provider-icon";
|
||||
import styles from "./auth-social-buttons.module.css";
|
||||
|
||||
export interface AuthSocialButtonsProps {
|
||||
@@ -37,10 +38,7 @@ export function AuthSocialButtons({
|
||||
disabled={loadingProvider !== null && loadingProvider !== "facebook"}
|
||||
>
|
||||
<span className={styles.icon} aria-hidden="true">
|
||||
{/* Facebook "f" logo placeholder */}
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M13 22v-8h3l1-4h-4V7.5c0-1.2.4-2 2-2h2V2.2C16.6 2.1 15.5 2 14.3 2 11.5 2 9.5 3.7 9.5 7v3h-3v4h3v8h3.5z" />
|
||||
</svg>
|
||||
<AuthProviderIcon provider="facebook" />
|
||||
</span>
|
||||
<span>Continue with Facebook</span>
|
||||
</button>
|
||||
@@ -55,25 +53,7 @@ export function AuthSocialButtons({
|
||||
disabled={loadingProvider !== null && loadingProvider !== "google"}
|
||||
>
|
||||
<span className={styles.icon} aria-hidden="true">
|
||||
{/* Google "G" logo placeholder */}
|
||||
<svg width="20" height="20" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M22 12.2c0-.7-.1-1.4-.2-2H12v3.8h5.6c-.2 1.3-1 2.4-2 3.1v2.6h3.2c1.9-1.7 2.9-4.2 2.9-7.5z"
|
||||
fill="#4285F4"
|
||||
/>
|
||||
<path
|
||||
d="M12 22c2.7 0 4.9-.9 6.5-2.4l-3.2-2.5c-.9.6-2 1-3.3 1-2.6 0-4.7-1.7-5.5-4.1H3.2v2.5C4.8 19.7 8.1 22 12 22z"
|
||||
fill="#34A853"
|
||||
/>
|
||||
<path
|
||||
d="M6.5 14a6 6 0 010-3.9V7.5H3.2a10 10 0 000 9l3.3-2.5z"
|
||||
fill="#FBBC05"
|
||||
/>
|
||||
<path
|
||||
d="M12 5.9c1.5 0 2.8.5 3.8 1.5l2.9-2.9C16.9 2.9 14.7 2 12 2 8.1 2 4.8 4.3 3.2 7.5L6.5 10c.8-2.4 2.9-4.1 5.5-4.1z"
|
||||
fill="#EA4335"
|
||||
/>
|
||||
</svg>
|
||||
<AuthProviderIcon provider="google" />
|
||||
</span>
|
||||
<span>Continue with Google</span>
|
||||
</button>
|
||||
@@ -87,9 +67,7 @@ export function AuthSocialButtons({
|
||||
disabled={loadingProvider !== null && loadingProvider !== "apple"}
|
||||
>
|
||||
<span className={styles.icon} aria-hidden="true">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M16.4 1.5c0 1.1-.4 2.1-1.1 2.9-.8.8-1.8 1.4-2.8 1.3-.1-1.1.4-2.2 1.1-3 .8-.8 1.9-1.3 2.8-1.2zM20 17.4c-.5 1.2-1.1 2.3-1.9 3.3-1 1.3-2.4 2.9-4.1 2.9-1.5 0-1.9-1-3.9-1-2 0-2.4 1-4 1-1.7 0-3-1.5-4-2.8-2.7-3.6-3-7.8-1.3-10 1.2-1.5 3-2.4 4.8-2.4 1.8 0 2.9 1 4.4 1 1.4 0 2.3-1 4.4-1 1.6 0 3.3.9 4.5 2.4-4 2.1-3.3 7.7.1 8.6z" />
|
||||
</svg>
|
||||
<AuthProviderIcon provider="apple" />
|
||||
</span>
|
||||
<span>Continue with Apple</span>
|
||||
</button>
|
||||
|
||||
@@ -11,6 +11,7 @@ export * from "./auth-legal-text";
|
||||
export * from "./auth-other-options-dialog";
|
||||
export * from "./auth-panel";
|
||||
export * from "./auth-primary-button";
|
||||
export * from "./auth-provider-icon";
|
||||
export * from "./auth-social-button";
|
||||
export * from "./auth-social-buttons";
|
||||
export * from "./auth-text-field";
|
||||
|
||||
Reference in New Issue
Block a user