From a382da99f257bd431def0350c5a755f2a1c89134 Mon Sep 17 00:00:00 2001 From: HoshinoSuzumi Date: Tue, 9 Apr 2024 03:26:48 +0800 Subject: [PATCH] feat: amateur radio satellite name and norad id search --- app/satellites/TransponderCard.tsx | 56 ++++++++ app/satellites/page.tsx | 216 ++++++++++++++++++++++------- app/satellites/styles.scss | 8 +- 3 files changed, 227 insertions(+), 53 deletions(-) create mode 100644 app/satellites/TransponderCard.tsx diff --git a/app/satellites/TransponderCard.tsx b/app/satellites/TransponderCard.tsx new file mode 100644 index 0000000..d19e3f1 --- /dev/null +++ b/app/satellites/TransponderCard.tsx @@ -0,0 +1,56 @@ +import {Transponder} from '@/app/satellites/page' +import {Icon} from '@iconify-icon/react' +import {rubik} from '@/app/fonts' + +export const TransponderCard = ({ + transponder, +}: { + transponder: Transponder +}) => { + return ( +
+
+
+ + + {transponder.mode || 'UNKNOWN MODE'} + +
+ {transponder.callsign || transponder.beacon && ( +
+ {transponder.callsign && ( +
+ + {transponder.callsign} +
+ )} + {transponder.beacon && ( +
+ + {transponder.beacon} +
+ )} +
+ )} +
+
+ + {transponder.uplink || '--'} +
+
+ + {transponder.downlink || '--'} +
+
+
+
+ ) +} \ No newline at end of file diff --git a/app/satellites/page.tsx b/app/satellites/page.tsx index a17c4f1..b47bee1 100644 --- a/app/satellites/page.tsx +++ b/app/satellites/page.tsx @@ -7,73 +7,166 @@ import {Input, Table} from '@douyinfe/semi-ui' import {IconSearch} from '@douyinfe/semi-icons' import useSWR from 'swr' import {ColumnProps} from '@douyinfe/semi-ui/lib/es/table' +import {Key, useRef, useState} from 'react' +import {TransponderCard} from '@/app/satellites/TransponderCard' + +export interface FrequenciesRawData { + status: string + name: string + norad_id: number + satnogs_id: string + uplink: string + downlink: string + beacon: string + mode: string +} + +export interface Transponder { + uplink?: string + downlink?: string + beacon?: string + mode?: string + callsign?: string + status: string +} + +export interface FrequenciesData { + name: string + norad_id: number + satnogs_id: string + transponders: Transponder[] +} export default function Page() { - const columns: ColumnProps<{ - status: string - name: string - mode: string - }>[] = [ - { - title: '状态', - dataIndex: 'status', - }, - { - title: '卫星名称', - dataIndex: 'name', - }, - { - title: 'NORAD ID', - dataIndex: 'norad_id', - }, - { - title: '上行', - dataIndex: 'uplink', - }, - { - title: '下行', - dataIndex: 'downlink', - }, - { - title: '信标', - dataIndex: 'beacon', - }, + const compositionRef = useRef({isComposition: false}) + const [filteredValue, setFilteredValue] = useState([]) + + const columns: ColumnProps[] = [ { - title: '模式', - dataIndex: 'mode', + title: '转发器', + dataIndex: 'transponders', + width: 100, + align: 'center', + render: (record) => ( +
+ {record?.map((transponder: Transponder, index: Key | null | undefined) => ( +
+ ))} +
+ ), filters: [ { text: 'FM', value: 'FM', }, { - text: 'VHF/UHF', - value: 'VHF/UHF', + text: 'CW', + value: 'CW', + }, + { + text: 'Linear', + value: 'Linear', + }, + { + text: 'SSB', + value: 'SSB', + }, + { + text: 'FSK', + value: 'FSK', + }, + { + text: 'AFSK', + value: 'AFSK', + }, + { + text: 'QPSK', + value: 'QPSK', }, ], onFilter: (value, record) => { - console.log(value, record?.mode) - return record?.mode?.includes(value) || false + return record?.transponders.some(item => item.mode?.includes(value)) || false + }, + }, + { + title: '卫星名称', + dataIndex: 'name', + sorter: (a, b) => a?.name.localeCompare(b?.name || '') || 0, + onFilter: (value, record) => { + const lowerValue = value.toLowerCase() + return record?.name.toLowerCase().includes(lowerValue) || `${record?.norad_id || ''}`.includes(lowerValue) || false }, + filteredValue, + }, + { + title: 'NORAD ID', + dataIndex: 'norad_id', + sorter: (a, b) => ((a?.norad_id || 0) - (b?.norad_id || 0)) || 0, + }, + { + title: 'SatNOGS ID', + dataIndex: 'satnogs_id', }, ] const { data: frequenciesData, isLoading: isFrequenciesLoading, - } = useSWR<[{ - status: string - name: string - norad_id: string - uplink: string - downlink: string - beacon: string - mode: string - }]>('https://mirror.ghproxy.com/https://raw.githubusercontent.com/palewire/ham-satellite-database/main/data/amsat-all-frequencies.json') + } = useSWR('https://mirror.ghproxy.com/https://raw.githubusercontent.com/palewire/ham-satellite-database/main/data/amsat-all-frequencies.json') + + const groupedFrequencies = frequenciesData?.reduce((acc, cur) => { + const existing = acc.find(item => item.name === cur.name) + if (!existing) { + acc.push({ + name: cur.name, + norad_id: cur.norad_id, + satnogs_id: cur.satnogs_id, + transponders: [ + { + uplink: cur.uplink, + downlink: cur.downlink, + beacon: cur.beacon, + mode: cur.mode, + status: cur.status, + }, + ], + }) + } else { + existing.transponders.push({ + uplink: cur.uplink, + downlink: cur.downlink, + beacon: cur.beacon, + mode: cur.mode, + status: cur.status, + }) + } + return acc + }, []) + + function handleCompositionStart() { + compositionRef.current.isComposition = true + } + + function handleCompositionEnd(event: any) { + compositionRef.current.isComposition = false + const value = event.target?.value + const newFilteredValue = value ? [value] : [] + setFilteredValue(newFilteredValue) + } - // const groupedFrequencies = frequenciesData?.reduce((acc, cur) => { - // const existing = acc. - // }, []) + function handleChange(value: any) { + if (compositionRef.current.isComposition) { + return + } + const newFilteredValue = value ? [value] : [] + setFilteredValue(newFilteredValue) + } return (
@@ -84,17 +177,38 @@ export default function Page() { Amateur Radio Satellites Database } + onCompositionStart={handleCompositionStart} + onCompositionEnd={handleCompositionEnd} + onChange={handleChange} />
-
+
} + expandedRowRender={(record) => ( +
+ {record?.transponders.map((transponder, index) => ( + + ))} +
+ )} + pagination={{ + pageSize: 30, + position: 'both', + formatPageText: (page) => `第 ${page?.currentStart}-${page?.currentEnd} 项,共 ${page?.total} 组`, + }} loading={isFrequenciesLoading} /> diff --git a/app/satellites/styles.scss b/app/satellites/styles.scss index b5ece4b..c8115fe 100644 --- a/app/satellites/styles.scss +++ b/app/satellites/styles.scss @@ -1,3 +1,7 @@ .semi-table-pagination-outer { - @apply px-4; -} \ No newline at end of file + @apply px-4 flex-wrap items-center; +} + +table { + @apply text-nowrap; +}