Skip to content

Commit 6713956

Browse files
authored
Merge pull request #46 from HORNET-Storage/ui/access-control
UI: Access control page
2 parents adf848e + 75dd04f commit 6713956

9 files changed

Lines changed: 239 additions & 182 deletions

File tree

src/components/blocked-pubkeys/BlockedPubkeys.styles.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,45 @@
11
import styled from 'styled-components';
2+
import Card from 'antd/lib/card/Card';
3+
import { Table, TableProps } from 'antd';
4+
import { Input } from 'antd';
5+
import { BaseCol } from '../common/BaseCol/BaseCol';
6+
export const InputRoot = styled(Input)`
7+
background-color: var(--layout-sider-bg-color);
8+
& input {
9+
background-color: var(--layout-sider-bg-color);
10+
}
11+
`;
12+
export const BaseColRoot = styled(BaseCol)`
13+
overflow: auto;
14+
border-radius: 8px;
15+
height: 100%;
16+
`;
17+
export const TableContainer = styled.div`
18+
border-radius: 12px;
19+
margin: 0 2px;
20+
padding-top: 0.4rem;
21+
padding-bottom: 2rem;
22+
background-color: var(--secondary-background-color);
23+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
24+
border: 1px solid var(--border-base-color);
25+
`;
26+
export const CardRoot = styled(Card)`
27+
border: none;
28+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
29+
background-color: var(--background-color);
30+
padding-left: 1.5rem;
31+
padding-right: 1.5rem;
32+
padding-top: 1rem;
33+
padding-bottom: 2rem;
34+
`;
235

336
export const HeaderWrapper = styled.div`
437
display: flex;
538
justify-content: space-between;
639
margin-bottom: 1.5rem;
740
flex-wrap: wrap;
841
gap: 1rem;
9-
42+
1043
@media (max-width: 768px) {
1144
flex-direction: column;
1245
}
@@ -54,3 +87,11 @@ export const CircularBadge = styled.div<{ color: string }>`
5487
font-weight: bold;
5588
margin-right: 8px;
5689
`;
90+
export const EmptyList = styled.div`
91+
min-height: 4rem;
92+
display: flex;
93+
align-items: center;
94+
justify-content: center;
95+
color: var(--text-light-color);
96+
border-bottom: none;
97+
`;
Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,45 @@
1-
import React, { useState } from 'react';
2-
import { Card, Space, Typography } from 'antd';
1+
import React, { useState, FC } from 'react';
2+
import { Space, Typography, Table, TableProps } from 'antd';
33
import useBlockedPubkeys from '@app/hooks/useBlockedPubkeys';
44
import { BaseButton } from '@app/components/common/BaseButton/BaseButton';
55
import { ReloadOutlined } from '@ant-design/icons';
66
import { BlockedPubkeysTable } from './components/BlockedPubkeysTable';
77
import { FlaggedPubkeysTable } from './components/FlaggedPubkeysTable';
88
import { BlockPubkeyForm } from './components/BlockPubkeyForm';
99
import { useModerationStats } from '@app/hooks/useModerationStats';
10+
import { LockFilled } from '@ant-design/icons';
11+
import styled from 'styled-components';
1012
import * as S from './BlockedPubkeys.styles';
1113

1214
const { Title, Text } = Typography;
1315

16+
export function createStyledTable<T extends object = any>() {
17+
const GenericTable: FC<TableProps<T>> = (props) => <Table {...props} />;
18+
19+
const StyledTable = styled(GenericTable)`
20+
border-radius: 12px;
21+
22+
& .ant-table-thead .ant-table-cell {
23+
background-color: var(--secondary-background-color);
24+
}
25+
26+
.ant-table-tbody {
27+
background-color: var(--layout-sider-bg-color);
28+
}
29+
.ant-table-placeholder .ant-table-cell {
30+
background-color: var(--layout-sider-bg-color);
31+
transition: none;
32+
}
33+
.ant-table-placeholder .ant-table-cell:hover {
34+
background-color: var(--layout-sider-bg-color);
35+
}
36+
`;
37+
return StyledTable;
38+
}
1439
export const BlockedPubkeys: React.FC = () => {
1540
const [activeView, setActiveView] = useState<'blocked' | 'flagged'>('blocked');
16-
const {
17-
blockedPubkeys,
18-
count,
19-
loading,
20-
fetchBlockedPubkeys,
21-
addBlockedPubkey,
22-
removeBlockedPubkey,
23-
} = useBlockedPubkeys();
41+
const { blockedPubkeys, count, loading, fetchBlockedPubkeys, addBlockedPubkey, removeBlockedPubkey } =
42+
useBlockedPubkeys();
2443
const { fetchStats, loading: statsLoading } = useModerationStats();
2544

2645
// Refresh all data
@@ -30,57 +49,41 @@ export const BlockedPubkeys: React.FC = () => {
3049
};
3150

3251
return (
33-
<Card>
34-
<Space direction="vertical" size="large" style={{ width: '100%' }}>
35-
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
36-
<div>
37-
<Title level={4}>Access Control</Title>
38-
<Text type="secondary">
39-
Control access to your relay and manage flagged pubkeys
40-
</Text>
52+
<S.BaseColRoot>
53+
<S.CardRoot>
54+
<Space direction="vertical" size="large" style={{ width: '100%' }}>
55+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
56+
<div>
57+
<Title level={3}>
58+
Access Control <LockFilled />
59+
</Title>
60+
<Text style={{ color: 'var(--text-light-color)' }}>
61+
Control access to your relay and manage flagged pubkeys
62+
</Text>
63+
</div>
64+
<BaseButton icon={<ReloadOutlined />} onClick={handleRefresh} loading={loading || statsLoading}>
65+
Refresh
66+
</BaseButton>
4167
</div>
42-
<BaseButton
43-
icon={<ReloadOutlined />}
44-
onClick={handleRefresh}
45-
loading={loading || statsLoading}
46-
>
47-
Refresh
48-
</BaseButton>
49-
</div>
50-
51-
{activeView === 'blocked' && (
52-
<BlockPubkeyForm onSubmit={addBlockedPubkey} disabled={loading} />
53-
)}
54-
55-
<S.NavContainer>
56-
<S.NavLink
57-
active={activeView === 'blocked'}
58-
onClick={() => setActiveView('blocked')}
59-
>
60-
Blocked Access
61-
</S.NavLink>
62-
<S.NavLink
63-
active={activeView === 'flagged'}
64-
onClick={() => setActiveView('flagged')}
65-
>
66-
Flagged Access
67-
</S.NavLink>
68-
</S.NavContainer>
69-
70-
{activeView === 'blocked' ? (
71-
<BlockedPubkeysTable
72-
blockedPubkeys={blockedPubkeys}
73-
loading={loading}
74-
onUnblock={removeBlockedPubkey}
75-
/>
76-
) : (
77-
<FlaggedPubkeysTable
78-
blockedPubkeys={blockedPubkeys}
79-
onBlock={addBlockedPubkey}
80-
disabled={loading}
81-
/>
82-
)}
83-
</Space>
84-
</Card>
68+
69+
{activeView === 'blocked' && <BlockPubkeyForm onSubmit={addBlockedPubkey} disabled={loading} />}
70+
71+
<S.NavContainer>
72+
<S.NavLink active={activeView === 'blocked'} onClick={() => setActiveView('blocked')}>
73+
Blocked Access
74+
</S.NavLink>
75+
<S.NavLink active={activeView === 'flagged'} onClick={() => setActiveView('flagged')}>
76+
Flagged Access
77+
</S.NavLink>
78+
</S.NavContainer>
79+
80+
{activeView === 'blocked' ? (
81+
<BlockedPubkeysTable blockedPubkeys={blockedPubkeys} loading={loading} onUnblock={removeBlockedPubkey} />
82+
) : (
83+
<FlaggedPubkeysTable blockedPubkeys={blockedPubkeys} onBlock={addBlockedPubkey} disabled={loading} />
84+
)}
85+
</Space>
86+
</S.CardRoot>
87+
</S.BaseColRoot>
8588
);
8689
};
Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
import React, { useState } from 'react';
22
import { Form, Input, Button, Card } from 'antd';
33
import { PlusOutlined } from '@ant-design/icons';
4+
import styled from 'styled-components';
5+
import { BREAKPOINTS } from '@app/styles/themes/constants';
46

57
interface BlockPubkeyFormProps {
68
onSubmit: (pubkey: string, reason?: string) => Promise<void>;
79
disabled: boolean;
810
}
11+
const CardRoot = styled(Card)`
12+
border-color: var(--border-base-color) !important;
13+
border-width: 1px;
14+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
15+
background-color: var(--secondary-background-color) !important;
916
10-
export const BlockPubkeyForm: React.FC<BlockPubkeyFormProps> = ({
11-
onSubmit,
12-
disabled,
13-
}) => {
17+
& .ant-card-head {
18+
border-bottom-color: var(--border-base-color) !important;
19+
}
20+
}
21+
`;
22+
const TextArea = styled(Input.TextArea)`
23+
background-color: var(--layout-sider-bg-color) !important;
24+
`;
25+
const InputArea = styled(Input)`
26+
background-color: var(--layout-sider-bg-color) !important;
27+
`;
28+
export const FormItemContainer = styled.div`
29+
width: 100%;
30+
@media screen and (min-width: ${BREAKPOINTS.md}px) {
31+
padding-right: 1.5rem;
32+
}
33+
`;
34+
35+
export const BlockPubkeyForm: React.FC<BlockPubkeyFormProps> = ({ onSubmit, disabled }) => {
1436
const [form] = Form.useForm();
1537
const [submitting, setSubmitting] = useState(false);
1638

@@ -36,42 +58,26 @@ export const BlockPubkeyForm: React.FC<BlockPubkeyFormProps> = ({
3658
};
3759

3860
return (
39-
<Card title="Block a Pubkey" size="small">
40-
<Form
41-
form={form}
42-
layout="vertical"
43-
onFinish={handleSubmit}
44-
>
45-
<Form.Item
46-
name="pubkey"
47-
label="Pubkey to block"
48-
rules={[{ validator: validatePubkey }]}
49-
>
50-
<Input placeholder="Enter the 64-character hex pubkey" />
51-
</Form.Item>
61+
<CardRoot title="Block a Pubkey" size="small">
62+
<Form form={form} layout="vertical" onFinish={handleSubmit}>
63+
<FormItemContainer>
64+
<Form.Item name="pubkey" label="Pubkey to block" rules={[{ validator: validatePubkey }]}>
65+
<InputArea placeholder="Enter the 64-character hex pubkey" />
66+
</Form.Item>
67+
</FormItemContainer>
5268

53-
<Form.Item
54-
name="reason"
55-
label="Reason (optional)"
56-
>
57-
<Input.TextArea
58-
placeholder="Enter reason for blocking this pubkey"
59-
rows={2}
60-
/>
61-
</Form.Item>
69+
<FormItemContainer>
70+
<Form.Item name="reason" label="Reason (optional)">
71+
<TextArea placeholder="Enter reason for blocking this pubkey" rows={2} />
72+
</Form.Item>
73+
</FormItemContainer>
6274

6375
<Form.Item>
64-
<Button
65-
type="primary"
66-
htmlType="submit"
67-
icon={<PlusOutlined />}
68-
loading={submitting}
69-
disabled={disabled}
70-
>
76+
<Button type="primary" htmlType="submit" icon={<PlusOutlined />} loading={submitting} disabled={disabled}>
7177
Block Pubkey
7278
</Button>
7379
</Form.Item>
7480
</Form>
75-
</Card>
81+
</CardRoot>
7682
);
7783
};

0 commit comments

Comments
 (0)