Add stock search and detail pages with charts, dividends and shared event rows. Use verified ticker links for portfolio names and logos, numeric dates and refreshed account cards. Update the generated API contract.
48 lines
897 B
TypeScript
48 lines
897 B
TypeScript
import { Anchor, Avatar } from "@mantine/core";
|
|
import type { FC } from "react";
|
|
import { useState } from "react";
|
|
import { Link } from "react-router";
|
|
|
|
type PositionLogoProps = {
|
|
src: string | null;
|
|
label: string;
|
|
to?: string;
|
|
};
|
|
|
|
const PositionLogo: FC<PositionLogoProps> = (props) => {
|
|
const { src, label } = props;
|
|
const [failed, setFailed] = useState(false);
|
|
|
|
const logo =
|
|
src && !failed ? (
|
|
<Avatar
|
|
src={src}
|
|
alt={label}
|
|
size={40}
|
|
radius="md"
|
|
onError={() => setFailed(true)}
|
|
/>
|
|
) : (
|
|
<Avatar size={40} radius="md">
|
|
{(label.trim()[0] ?? "?").toUpperCase()}
|
|
</Avatar>
|
|
);
|
|
return props.to ? (
|
|
<Anchor
|
|
component={Link}
|
|
to={props.to}
|
|
aria-label={label}
|
|
c="inherit"
|
|
underline="never"
|
|
display="block"
|
|
style={{ borderRadius: "var(--mantine-radius-md)" }}
|
|
>
|
|
{logo}
|
|
</Anchor>
|
|
) : (
|
|
logo
|
|
);
|
|
};
|
|
|
|
export { PositionLogo };
|