diff --git a/apps/user_dashboard/src/components/connected_apps/connected_apps.module.scss b/apps/user_dashboard/src/components/connected_apps/connected_apps.module.scss new file mode 100644 index 000000000..372c9da09 --- /dev/null +++ b/apps/user_dashboard/src/components/connected_apps/connected_apps.module.scss @@ -0,0 +1,22 @@ +.emptyState { + margin-top: 24px; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: fit-content; + padding-left: 45px; + gap: 8px; + + text-align: center; +} + +.emptyImage { + width: 176px; + height: 146px; +} + +.emptyImageWrapper { + padding: 26.8px 65.3px 26.6px 28.6px; +} diff --git a/apps/user_dashboard/src/components/connected_apps/connected_apps.tsx b/apps/user_dashboard/src/components/connected_apps/connected_apps.tsx index 97210999d..a59419f1e 100644 --- a/apps/user_dashboard/src/components/connected_apps/connected_apps.tsx +++ b/apps/user_dashboard/src/components/connected_apps/connected_apps.tsx @@ -1,12 +1,42 @@ import { type FC } from "react"; import { Typography } from "@oko-wallet/oko-common-ui/typography"; +import { ImageWithAlt } from "@oko-wallet/oko-common-ui/imageWithAlt"; + +import styles from "./connected_apps.module.scss"; export const ConnectedApps: FC = () => { + //TODO: remove this after Connected-App feature is implemented + const isEmpty = true; + + const emptyImage = `${process.env.NEXT_PUBLIC_S3_BUCKET_URL}/assets/oko_user_dashboard_connected_app_empty.webp`; + const emptyImageAlt = `${process.env.NEXT_PUBLIC_S3_BUCKET_URL}/assets/oko_user_dashboard_connected_app_empty.png`; + return (
Connected Apps + + {isEmpty && ( +
+ {isEmpty && ( +
+ +
+ )} + + No Connected Apps Yet + + + Log in to an app with Oko to see it here. + +
+ )}
); }; diff --git a/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.module.scss b/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.module.scss index 2af899edc..b9fbb861a 100644 --- a/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.module.scss +++ b/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.module.scss @@ -68,3 +68,34 @@ .hideLowBalanceLabel { cursor: pointer; } + +.emptyState { + margin-top: 12px; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + + text-align: center; + gap: 8px; + + .emptyImage { + width: 122px; + height: 154px; + + margin-top: 23px; + } + + .showHideChainsLink { + text-decoration: underline; + cursor: pointer; + + transition: color 0.15s ease; + &:hover { + color: var(--text-quaternary-on-brand); + } + } +} diff --git a/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.tsx b/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.tsx index ac92e1c64..27104ad2b 100644 --- a/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.tsx +++ b/apps/user_dashboard/src/components/my_assets/components/token_list/token_list.tsx @@ -1,15 +1,17 @@ -import { type ChangeEvent, Fragment, useState } from "react"; +import { type ChangeEvent, type FC, Fragment, useState } from "react"; import { observer } from "mobx-react-lite"; import { CoinPretty } from "@keplr-wallet/unit"; import { SearchIcon } from "@oko-wallet/oko-common-ui/icons/search"; import { Typography } from "@oko-wallet/oko-common-ui/typography"; import { CheckCircleOutlinedIcon } from "@oko-wallet/oko-common-ui/icons/check_circle_outlined"; +import { ImageWithAlt } from "@oko-wallet/oko-common-ui/image_with_alt"; import styles from "./token_list.module.scss"; import { TokenItem } from "../token_item/token_item"; import { useRootStore } from "@oko-wallet-user-dashboard/state/store"; import { useSearch } from "@oko-wallet-user-dashboard/hooks/use_search"; import type { ViewToken } from "@oko-wallet-user-dashboard/store_legacy/huge-queries"; +import { ShowHideChainsModal } from "@oko-wallet-user-dashboard/components/show_hide_chains_modal/show_hide_chains_modal"; export const TokenList = observer(() => { const { hugeQueriesStore, chainStore, okoWalletAddressStore } = @@ -97,7 +99,44 @@ export const TokenList = observer(() => { ); })} + {balances.length === 0 && } ); }); + +const EmptyState: FC = () => { + const emptyImage = `${process.env.NEXT_PUBLIC_S3_BUCKET_URL}/assets/oko_user_dashboard_assets_empty.webp`; + const emptyImageAlt = `${process.env.NEXT_PUBLIC_S3_BUCKET_URL}/assets/oko_user_dashboard_assets_empty.png`; + + return ( +
+ + + + No Assets Found + + + + If you have assets but they’re not appearing, please check if Hide Low{" "} + Balance is turned on or if the chain is hidden in{" "} + ( + + Show/Hide Chains + + )} + /> + +
+ ); +}; diff --git a/apps/user_dashboard/src/components/widgets/account_widget/account_widget.tsx b/apps/user_dashboard/src/components/widgets/account_widget/account_widget.tsx index 96c602319..ba0f59e4f 100644 --- a/apps/user_dashboard/src/components/widgets/account_widget/account_widget.tsx +++ b/apps/user_dashboard/src/components/widgets/account_widget/account_widget.tsx @@ -8,6 +8,7 @@ import { LoginWidget } from "../login_widget/login_widget"; import { Spinner } from "../../spinner/spinner"; import { paths } from "@oko-wallet-user-dashboard/paths"; import { useRouter } from "next/navigation"; +import type { AuthType } from "@oko-wallet/oko-types/auth"; import styles from "./account_widget.module.scss"; @@ -26,13 +27,9 @@ export const AccountWidget: FC = () => { const setAuthType = useUserInfoState((state) => state.setAuthType); // TODO: add other login methods, and update the type accordingly - const [loginMethod, setLoginMethod] = useState< - "email" | "google" | "telegram" | "x" | "apple" - >("google"); + const [loginMethod, setLoginMethod] = useState("google"); - async function handleSignIn( - method: "email" | "google" | "telegram" | "x" | "apple", - ) { + async function handleSignIn(method: AuthType) { setLoginMethod(method); if (!okoWallet) { @@ -40,16 +37,22 @@ export const AccountWidget: FC = () => { return; } - if (method !== "google" && method !== "email") { + if ( + method !== "google" && + method !== "auth0" && + method !== "telegram" && + method !== "x" && + method !== "discord" + ) { console.error("Unsupported login method atm: %s", method); return; } try { setSigningInState({ status: "signing-in" }); - await okoWallet.signIn(method); + await okoWallet.signIn(method === "auth0" ? "email" : method); - setAuthType(method === "google" ? "google" : "auth0"); + setAuthType(method); setSigningInState({ status: "ready" }); } catch (error: any) { console.error("sign in fail, err: %s", error); @@ -81,7 +84,7 @@ export const AccountWidget: FC = () => { } // The email login loading progress is shown in the Attached popup, so we don't need to show that here - if (signingInState.status === "signing-in" && loginMethod !== "email") { + if (signingInState.status === "signing-in" && loginMethod !== "auth0") { return ; } diff --git a/apps/user_dashboard/src/components/widgets/account_widget/auth_progress_widget.tsx b/apps/user_dashboard/src/components/widgets/account_widget/auth_progress_widget.tsx index 69504e0e0..e6084bb13 100644 --- a/apps/user_dashboard/src/components/widgets/account_widget/auth_progress_widget.tsx +++ b/apps/user_dashboard/src/components/widgets/account_widget/auth_progress_widget.tsx @@ -5,14 +5,15 @@ import { Typography } from "@oko-wallet/oko-common-ui/typography"; import { Spacing } from "@oko-wallet/oko-common-ui/spacing"; import { TelegramIcon } from "@oko-wallet/oko-common-ui/icons/telegram_icon"; import { XIcon } from "@oko-wallet/oko-common-ui/icons/x_icon"; -import { AppleIcon } from "@oko-wallet/oko-common-ui/icons/apple_icon"; import { MailboxIcon } from "@oko-wallet/oko-common-ui/icons/mailbox"; +import { DiscordIcon } from "@oko-wallet/oko-common-ui/icons/discord_icon"; +import type { AuthType } from "@oko-wallet/oko-types/auth"; import styles from "./auth_progress_widget.module.scss"; import { Spinner } from "@oko-wallet-user-dashboard/components/spinner/spinner"; type AuthProgressWidgetProps = { - method: "email" | "google" | "telegram" | "x" | "apple"; + method: AuthType; status?: "loading" | "failed"; onRetry?: () => void; }; @@ -27,13 +28,11 @@ export const AuthProgressWidget: FC = ({ return (
- {method === "email" && ( - - )} + {method === "auth0" && } {method === "google" && } {method === "telegram" && } {method === "x" && } - {method === "apple" && } + {method === "discord" && } void; + onSignIn: (method: AuthType) => void; onShowSocials: () => void; } @@ -25,7 +31,7 @@ export const LoginDefaultView: FC = ({ variant="secondary" size="md" fullWidth - onClick={() => onSignIn("email")} + onClick={() => onSignIn("auth0")} > @@ -42,17 +48,11 @@ export const LoginDefaultView: FC = ({ Google - {/* */} +
); diff --git a/apps/user_dashboard/src/components/widgets/login_widget/login_socials_view.tsx b/apps/user_dashboard/src/components/widgets/login_widget/login_socials_view.tsx index 513bbfe69..1f205931a 100644 --- a/apps/user_dashboard/src/components/widgets/login_widget/login_socials_view.tsx +++ b/apps/user_dashboard/src/components/widgets/login_widget/login_socials_view.tsx @@ -3,7 +3,8 @@ import { Button } from "@oko-wallet/oko-common-ui/button"; import { Typography } from "@oko-wallet/oko-common-ui/typography"; import { TelegramIcon } from "@oko-wallet/oko-common-ui/icons/telegram_icon"; import { XIcon } from "@oko-wallet/oko-common-ui/icons/x_icon"; -import { AppleIcon } from "@oko-wallet/oko-common-ui/icons/apple_icon"; +import { DiscordIcon } from "@oko-wallet-common-ui/icons/discord_icon"; +import type { AuthType } from "@oko-wallet/oko-types/auth"; import { ChevronLeftIcon } from "@oko-wallet/oko-common-ui/icons/chevron_left"; import { Spacing } from "@oko-wallet/oko-common-ui/spacing"; @@ -11,7 +12,7 @@ import styles from "./login_widget.module.scss"; export interface LoginSocialsViewProps { onBack: () => void; - onSignIn: (method: "telegram" | "x" | "apple") => void; + onSignIn: (method: AuthType) => void; } export const LoginSocialsView: FC = ({ @@ -67,8 +68,24 @@ export const LoginSocialsView: FC = ({ Telegram - + + {/* + */}
); diff --git a/apps/user_dashboard/src/components/widgets/login_widget/login_widget.tsx b/apps/user_dashboard/src/components/widgets/login_widget/login_widget.tsx index f51e729df..9bf5e5457 100644 --- a/apps/user_dashboard/src/components/widgets/login_widget/login_widget.tsx +++ b/apps/user_dashboard/src/components/widgets/login_widget/login_widget.tsx @@ -1,11 +1,12 @@ import { type FC, useState } from "react"; +import type { AuthType } from "@oko-wallet/oko-types/auth"; import styles from "./login_widget.module.scss"; import { LoginDefaultView } from "./login_default_view"; import { LoginSocialsView } from "./login_socials_view"; export interface LoginWidgetProps { - onSignIn: (method: "email" | "google" | "telegram" | "x" | "apple") => void; + onSignIn: (method: AuthType) => void; } export const LoginWidget: FC = ({ onSignIn }) => { diff --git a/apps/user_dashboard/src/state/user_info.ts b/apps/user_dashboard/src/state/user_info.ts index 8f11c1627..c324352c8 100644 --- a/apps/user_dashboard/src/state/user_info.ts +++ b/apps/user_dashboard/src/state/user_info.ts @@ -1,12 +1,12 @@ import { create } from "zustand"; import { combine, createJSONStorage, persist } from "zustand/middleware"; -import type { OAuthProvider } from "@oko-wallet/oko-types/auth"; +import type { AuthType } from "@oko-wallet/oko-types/auth"; interface UserInfoState { email: string | null; publicKey: string | null; isSignedIn: boolean; - authType: OAuthProvider | null; + authType: AuthType | null; } interface UserInfoActions { @@ -14,7 +14,7 @@ interface UserInfoActions { email: string | null; publicKey: string | null; }) => void; - setAuthType: (authType: OAuthProvider | null) => void; + setAuthType: (authType: AuthType | null) => void; clearUserInfo: () => void; } diff --git a/ui/oko_common_ui/package.json b/ui/oko_common_ui/package.json index 4b0c3b608..3a7735e78 100644 --- a/ui/oko_common_ui/package.json +++ b/ui/oko_common_ui/package.json @@ -24,7 +24,8 @@ "./toggle": "./src/toggle/toggle.tsx", "./tooltip": "./src/tooltip/tooltip.tsx", "./typography": "./src/typography/typography.tsx", - "./skeleton": "./src/skeleton/skeleton.tsx" + "./skeleton": "./src/skeleton/skeleton.tsx", + "./image_with_alt": "./src/image_with_alt/image_with_alt.tsx" }, "dependencies": { "@floating-ui/dom": "^1.7.4", diff --git a/ui/oko_common_ui/src/image_with_alt/image_with_alt.tsx b/ui/oko_common_ui/src/image_with_alt/image_with_alt.tsx new file mode 100644 index 000000000..d8e7dced0 --- /dev/null +++ b/ui/oko_common_ui/src/image_with_alt/image_with_alt.tsx @@ -0,0 +1,23 @@ +import type { FC } from "react"; + +interface ImageWithAltProps { + srcSet: string; + srcAlt: string; + alt: string; + style?: React.CSSProperties; + className?: string; +} +export const ImageWithAlt: FC = ({ + srcSet, + srcAlt, + alt, + style, + className, +}) => { + return ( + + + {alt} + + ); +};