Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<Typography tagType="h1" size="xl" weight="semibold" color="primary">
Connected Apps
</Typography>

{isEmpty && (
<div className={styles.emptyState}>
{isEmpty && (
<div className={styles.emptyImageWrapper}>
<ImageWithAlt
srcSet={emptyImage}
srcAlt={emptyImageAlt}
alt="Empty Connected Apps Image"
className={styles.emptyImage}
/>
</div>
)}
<Typography tagType="p" size="sm" weight="semibold" color="tertiary">
No Connected Apps Yet
</Typography>
<Typography tagType="p" size="sm" weight="medium" color="quaternary">
Log in to an app with Oko to see it here.
</Typography>
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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 } =
Expand Down Expand Up @@ -97,7 +99,44 @@ export const TokenList = observer(() => {
</Fragment>
);
})}
{balances.length === 0 && <EmptyState />}
</div>
</>
);
});

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 (
<div className={styles.emptyState}>
<ImageWithAlt
srcSet={emptyImage}
srcAlt={emptyImageAlt}
alt="Empty Assets Image"
className={styles.emptyImage}
/>

<Typography tagType="p" size="sm" weight="semibold" color="tertiary">
No Assets Found
</Typography>

<Typography tagType="p" size="sm" weight="medium" color="quaternary">
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{" "}
<ShowHideChainsModal
renderTrigger={({ onOpen }) => (
<span
className={styles.showHideChainsLink}
aria-role="button"
onClick={onOpen}
>
Show/Hide Chains
</span>
)}
/>
</Typography>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -26,30 +27,32 @@ export const AccountWidget: FC<AccountWidgetProps> = () => {
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<AuthType>("google");

async function handleSignIn(
method: "email" | "google" | "telegram" | "x" | "apple",
) {
async function handleSignIn(method: AuthType) {
setLoginMethod(method);

if (!okoWallet) {
console.error("okoWallet is not initialized");
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);
Expand Down Expand Up @@ -81,7 +84,7 @@ export const AccountWidget: FC<AccountWidgetProps> = () => {
}

// 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 <AuthProgressWidget method={loginMethod} status="loading" />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -27,13 +28,11 @@ export const AuthProgressWidget: FC<AuthProgressWidgetProps> = ({
return (
<div className={cn(styles.signingInWrapper, { [styles.failed]: isFailed })}>
<div className={styles.signingInCircle}>
{method === "email" && (
<MailboxIcon size={36} color="var(--fg-tertiary)" />
)}
{method === "auth0" && <MailboxIcon size={36} />}
{method === "google" && <GoogleIcon width={48} height={48} />}
{method === "telegram" && <TelegramIcon size={48} />}
{method === "x" && <XIcon size={48} />}
{method === "apple" && <AppleIcon size={48} />}
{method === "discord" && <DiscordIcon size={48} />}
<Spinner
size={62}
className={styles.spinnerOverlay}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ import { GoogleIcon } from "@oko-wallet/oko-common-ui/icons/google_icon";
import { Logo } from "@oko-wallet/oko-common-ui/logo";
import { Spacing } from "@oko-wallet/oko-common-ui/spacing";
import { MailboxIcon } from "@oko-wallet/oko-common-ui/icons/mailbox";
import { DiscordIcon } from "@oko-wallet/oko-common-ui/icons/discord_icon";
import { ChevronRightIcon } from "@oko-wallet/oko-common-ui/icons/chevron_right";
import { XIcon } from "@oko-wallet/oko-common-ui/icons/x_icon";
import { TelegramIcon } from "@oko-wallet/oko-common-ui/icons/telegram_icon";
import { Typography } from "@oko-wallet/oko-common-ui/typography";
import type { AuthType } from "@oko-wallet/oko-types/auth";

import styles from "./login_widget.module.scss";

export interface LoginDefaultViewProps {
onSignIn: (method: "email" | "google" | "telegram" | "x" | "apple") => void;
onSignIn: (method: AuthType) => void;
onShowSocials: () => void;
}

Expand All @@ -25,7 +31,7 @@ export const LoginDefaultView: FC<LoginDefaultViewProps> = ({
variant="secondary"
size="md"
fullWidth
onClick={() => onSignIn("email")}
onClick={() => onSignIn("auth0")}
>
<MailboxIcon size={20} color={"var(--fg-tertiary)"} />
<Spacing width={2} />
Expand All @@ -42,17 +48,11 @@ export const LoginDefaultView: FC<LoginDefaultViewProps> = ({
Google
</Button>

{/* <Button
variant="secondary"
size="md"
fullWidth
onClick={onShowSocials}
disabled={true} // TODO: Remove this once we have other social login implemented
>
<Button variant="secondary" size="md" fullWidth onClick={onShowSocials}>
<div className={styles.socialIconWrapper}>
<XIcon size={16} />
<TelegramIcon size={16} />
<AppleIcon size={16} />
<DiscordIcon size={16} />
</div>
<Typography
size="sm"
Expand All @@ -63,7 +63,7 @@ export const LoginDefaultView: FC<LoginDefaultViewProps> = ({
Other Socials
</Typography>
<ChevronRightIcon size={20} color={"var(--fg-quaternary)"} />
</Button> */}
</Button>
</div>
</Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ 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";

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<LoginSocialsViewProps> = ({
Expand Down Expand Up @@ -67,8 +68,24 @@ export const LoginSocialsView: FC<LoginSocialsViewProps> = ({
Telegram
</Typography>
</Button>

<Button
variant="secondary"
size="md"
fullWidth
onClick={() => onSignIn("discord")}
>
<DiscordIcon size={20} />
<Typography
size="sm"
weight="semibold"
color="secondary"
style={{ padding: "0 2px" }}
>
Discord
</Typography>
</Button>

{/* <Button
variant="secondary"
size="md"
fullWidth
Expand All @@ -83,7 +100,7 @@ export const LoginSocialsView: FC<LoginSocialsViewProps> = ({
>
Apple
</Typography>
</Button>
</Button> */}
</div>
</Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<LoginWidgetProps> = ({ onSignIn }) => {
Expand Down
Loading