reference-data.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. "use client";
  2. import { Badge } from "@pythnetwork/component-library/Badge";
  3. import { Table } from "@pythnetwork/component-library/Table";
  4. import { useMemo } from "react";
  5. import { useCollator } from "react-aria";
  6. import styles from "./reference-data.module.scss";
  7. import { LiveValue } from "../LivePrices";
  8. type Props = {
  9. feed: {
  10. symbol: string;
  11. product: {
  12. display_symbol: string;
  13. asset_type: string;
  14. description: string;
  15. price_account: string;
  16. base?: string | undefined;
  17. country?: string | undefined;
  18. quote_currency?: string | undefined;
  19. tenor?: string | undefined;
  20. cms_symbol?: string | undefined;
  21. cqs_symbol?: string | undefined;
  22. nasdaq_symbol?: string | undefined;
  23. generic_symbol?: string | undefined;
  24. weekly_schedule?: string | undefined;
  25. schedule?: string | undefined;
  26. contract_id?: string | undefined;
  27. };
  28. price: {
  29. exponent: number;
  30. numComponentPrices: number;
  31. numQuoters: number;
  32. minPublishers: number;
  33. lastSlot: bigint;
  34. validSlot: bigint;
  35. };
  36. };
  37. };
  38. export const ReferenceData = ({ feed }: Props) => {
  39. const collator = useCollator();
  40. const rows = useMemo(
  41. () =>
  42. [
  43. ...Object.entries({
  44. "Asset Type": (
  45. <Badge variant="neutral" style="outline" size="xs">
  46. {feed.product.asset_type.toUpperCase()}
  47. </Badge>
  48. ),
  49. Base: feed.product.base,
  50. Description: feed.product.description,
  51. Symbol: feed.symbol,
  52. Country: feed.product.country,
  53. "Quote Currency": feed.product.quote_currency,
  54. Tenor: feed.product.tenor,
  55. "CMS Symbol": feed.product.cms_symbol,
  56. "CQS Symbol": feed.product.cqs_symbol,
  57. "NASDAQ Symbol": feed.product.nasdaq_symbol,
  58. "Generic Symbol": feed.product.generic_symbol,
  59. "Weekly Schedule": feed.product.weekly_schedule,
  60. Schedule: feed.product.schedule,
  61. "Contract ID": feed.product.contract_id,
  62. "Display Symbol": feed.product.display_symbol,
  63. }),
  64. ...Object.entries({
  65. Exponent: "exponent",
  66. "Number of Price Components": "numComponentPrices",
  67. "Number of Price Quoters": "numQuoters",
  68. "Minimum Number of Publishers": "minPublishers",
  69. "Last Slot": "lastSlot",
  70. "Valid Slot": "validSlot",
  71. } as const).map(
  72. ([key, value]) =>
  73. [
  74. key,
  75. <span key={key} className={styles.value}>
  76. <LiveValue feed={feed} field={value} />
  77. </span>,
  78. ] as const,
  79. ),
  80. ]
  81. .map(([field, value]) =>
  82. value === undefined ? undefined : ([field, value] as const),
  83. )
  84. .filter((entry) => entry !== undefined)
  85. .sort(([a], [b]) => collator.compare(a, b))
  86. .map(([field, value]) => ({
  87. id: field,
  88. data: {
  89. field: <span className={styles.field}>{field}</span>,
  90. value:
  91. typeof value === "string" ? (
  92. <span className={styles.value}>{value}</span>
  93. ) : (
  94. value
  95. ),
  96. },
  97. })),
  98. [collator, feed],
  99. );
  100. return (
  101. <Table
  102. label="Reference Data"
  103. fill
  104. className={styles.referenceData}
  105. columns={[
  106. {
  107. id: "field",
  108. name: "Field",
  109. alignment: "left",
  110. isRowHeader: true,
  111. sticky: true,
  112. },
  113. { id: "value", name: "Value", fill: true, alignment: "left" },
  114. ]}
  115. rows={rows}
  116. />
  117. );
  118. };