diff --git a/src/pages/realms/[id].tsx b/src/pages/realms/[id].tsx new file mode 100644 index 0000000..cada062 --- /dev/null +++ b/src/pages/realms/[id].tsx @@ -0,0 +1,201 @@ +import { + Alert, + Avatar, + Box, + Button, + Card, + CardContent, + Checkbox, + Collapse, + Container, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from '@mui/material' +import { GetServerSideProps } from 'next' +import { checkAuthenticatedClient, getAttachmentUrl, redirectToLogin, sni, useUserStore } from 'solar-js-sdk' +import { useEffect, useState } from 'react' + +import PublicIcon from '@mui/icons-material/Public' +import ErrorIcon from '@mui/icons-material/Error' + +export const getServerSideProps = (async (context) => { + const id = context.params!.id as string[] + try { + const { data: realm } = await sni.get('/cgi/id/realms/' + id) + return { props: { realm, title: `Realm ${realm.name} / Solar Network` } } + } catch (err) { + console.error(err) + return { + notFound: true, + } + } +}) satisfies GetServerSideProps<{ realm: any }> + +export default function Realm({ realm }: any) { + useEffect(() => { + if (!checkAuthenticatedClient()) redirectToLogin() + }, []) + + const user = useUserStore() + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const [joined, setJoined] = useState(false) + + const [publicChannels, setPublicChannels] = useState([]) + const [checkedChannels, setCheckedChannels] = useState([]) + + function handleCheckChannel(value: string) { + const currentIndex = checkedChannels.indexOf(value) + const newChecked = [...checkedChannels] + + if (currentIndex === -1) { + newChecked.push(value) + } else { + newChecked.splice(currentIndex, 1) + } + + setCheckedChannels(newChecked) + } + + async function fetchPublicChannels() { + try { + const { data: channels } = await sni.get('/cgi/im/channels/' + realm.alias) + setPublicChannels(channels) + } catch (err) { + console.error(err) + } + } + + useEffect(() => { + fetchPublicChannels() + }, [realm]) + + async function joinRealm() { + setLoading(true) + try { + await sni.post('/cgi/id/realms/' + realm.id + '/members', { + related: user.account!.name, + }) + setLoading(false) + await joinChannels() + setJoined(true) + } catch (err: any) { + console.error(err) + setError(err.toString()) + } finally { + setLoading(false) + } + } + + async function joinChannels() { + try { + for (const chan of checkedChannels) { + await sni.post('/cgi/im/channels/' + realm.alias + '/' + chan + '/members', { + related: user.account!.name, + }) + } + } catch (err: any) { + console.error(err) + setError(err.toString()) + } + } + + return ( + + + + + + + {realm.name} + + + @{realm.alias} + + {realm.description} + + {publicChannels.length > 0 && ( + + + Public channels in this realm you can join + + + {publicChannels.map((value) => { + const labelId = `checkbox-list-label-${value}` + + return ( + + handleCheckChannel(value.alias)} + dense + > + + + + + + + ) + })} + + + )} + + {realm.isCommunity && ( + + + + + A community realm, you can join it as you wish. + + + + )} + + + } severity="error"> + {error} + + + + {joined ? ( + + Joined, check it out in the app + + ) : ( + + )} + + + + + ) +}