Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion src/components/blocked-pubkeys/BlockedPubkeys.styles.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,45 @@
import styled from 'styled-components';
import Card from 'antd/lib/card/Card';
import { Table, TableProps } from 'antd';
import { Input } from 'antd';
import { BaseCol } from '../common/BaseCol/BaseCol';
export const InputRoot = styled(Input)`
background-color: var(--layout-sider-bg-color);
& input {
background-color: var(--layout-sider-bg-color);
}
`;
export const BaseColRoot = styled(BaseCol)`
overflow: auto;
border-radius: 8px;
height: 100%;
`;
export const TableContainer = styled.div`
border-radius: 12px;
margin: 0 2px;
padding-top: 0.4rem;
padding-bottom: 2rem;
background-color: var(--secondary-background-color);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
border: 1px solid var(--border-base-color);
`;
export const CardRoot = styled(Card)`
border: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
background-color: var(--background-color);
padding-left: 1.5rem;
padding-right: 1.5rem;
padding-top: 1rem;
padding-bottom: 2rem;
`;

export const HeaderWrapper = styled.div`
display: flex;
justify-content: space-between;
margin-bottom: 1.5rem;
flex-wrap: wrap;
gap: 1rem;

@media (max-width: 768px) {
flex-direction: column;
}
Expand Down Expand Up @@ -54,3 +87,11 @@ export const CircularBadge = styled.div<{ color: string }>`
font-weight: bold;
margin-right: 8px;
`;
export const EmptyList = styled.div`
min-height: 4rem;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-light-color);
border-bottom: none;
`;
125 changes: 64 additions & 61 deletions src/components/blocked-pubkeys/BlockedPubkeys.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
import React, { useState } from 'react';
import { Card, Space, Typography } from 'antd';
import React, { useState, FC } from 'react';
import { Space, Typography, Table, TableProps } from 'antd';
import useBlockedPubkeys from '@app/hooks/useBlockedPubkeys';
import { BaseButton } from '@app/components/common/BaseButton/BaseButton';
import { ReloadOutlined } from '@ant-design/icons';
import { BlockedPubkeysTable } from './components/BlockedPubkeysTable';
import { FlaggedPubkeysTable } from './components/FlaggedPubkeysTable';
import { BlockPubkeyForm } from './components/BlockPubkeyForm';
import { useModerationStats } from '@app/hooks/useModerationStats';
import { LockFilled } from '@ant-design/icons';
import styled from 'styled-components';
import * as S from './BlockedPubkeys.styles';

const { Title, Text } = Typography;

export function createStyledTable<T extends object = any>() {
const GenericTable: FC<TableProps<T>> = (props) => <Table {...props} />;

const StyledTable = styled(GenericTable)`
border-radius: 12px;

& .ant-table-thead .ant-table-cell {
background-color: var(--secondary-background-color);
}

.ant-table-tbody {
background-color: var(--layout-sider-bg-color);
}
.ant-table-placeholder .ant-table-cell {
background-color: var(--layout-sider-bg-color);
transition: none;
}
.ant-table-placeholder .ant-table-cell:hover {
background-color: var(--layout-sider-bg-color);
}
`;
return StyledTable;
}
export const BlockedPubkeys: React.FC = () => {
const [activeView, setActiveView] = useState<'blocked' | 'flagged'>('blocked');
const {
blockedPubkeys,
count,
loading,
fetchBlockedPubkeys,
addBlockedPubkey,
removeBlockedPubkey,
} = useBlockedPubkeys();
const { blockedPubkeys, count, loading, fetchBlockedPubkeys, addBlockedPubkey, removeBlockedPubkey } =
useBlockedPubkeys();
const { fetchStats, loading: statsLoading } = useModerationStats();

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

return (
<Card>
<Space direction="vertical" size="large" style={{ width: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<Title level={4}>Access Control</Title>
<Text type="secondary">
Control access to your relay and manage flagged pubkeys
</Text>
<S.BaseColRoot>
<S.CardRoot>
<Space direction="vertical" size="large" style={{ width: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<Title level={3}>
Access Control <LockFilled />
</Title>
<Text style={{ color: 'var(--text-light-color)' }}>
Control access to your relay and manage flagged pubkeys
</Text>
</div>
<BaseButton icon={<ReloadOutlined />} onClick={handleRefresh} loading={loading || statsLoading}>
Refresh
</BaseButton>
</div>
<BaseButton
icon={<ReloadOutlined />}
onClick={handleRefresh}
loading={loading || statsLoading}
>
Refresh
</BaseButton>
</div>

{activeView === 'blocked' && (
<BlockPubkeyForm onSubmit={addBlockedPubkey} disabled={loading} />
)}

<S.NavContainer>
<S.NavLink
active={activeView === 'blocked'}
onClick={() => setActiveView('blocked')}
>
Blocked Access
</S.NavLink>
<S.NavLink
active={activeView === 'flagged'}
onClick={() => setActiveView('flagged')}
>
Flagged Access
</S.NavLink>
</S.NavContainer>

{activeView === 'blocked' ? (
<BlockedPubkeysTable
blockedPubkeys={blockedPubkeys}
loading={loading}
onUnblock={removeBlockedPubkey}
/>
) : (
<FlaggedPubkeysTable
blockedPubkeys={blockedPubkeys}
onBlock={addBlockedPubkey}
disabled={loading}
/>
)}
</Space>
</Card>

{activeView === 'blocked' && <BlockPubkeyForm onSubmit={addBlockedPubkey} disabled={loading} />}

<S.NavContainer>
<S.NavLink active={activeView === 'blocked'} onClick={() => setActiveView('blocked')}>
Blocked Access
</S.NavLink>
<S.NavLink active={activeView === 'flagged'} onClick={() => setActiveView('flagged')}>
Flagged Access
</S.NavLink>
</S.NavContainer>

{activeView === 'blocked' ? (
<BlockedPubkeysTable blockedPubkeys={blockedPubkeys} loading={loading} onUnblock={removeBlockedPubkey} />
) : (
<FlaggedPubkeysTable blockedPubkeys={blockedPubkeys} onBlock={addBlockedPubkey} disabled={loading} />
)}
</Space>
</S.CardRoot>
</S.BaseColRoot>
);
};
74 changes: 40 additions & 34 deletions src/components/blocked-pubkeys/components/BlockPubkeyForm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
import React, { useState } from 'react';
import { Form, Input, Button, Card } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import styled from 'styled-components';
import { BREAKPOINTS } from '@app/styles/themes/constants';

interface BlockPubkeyFormProps {
onSubmit: (pubkey: string, reason?: string) => Promise<void>;
disabled: boolean;
}
const CardRoot = styled(Card)`
border-color: var(--border-base-color) !important;
border-width: 1px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
background-color: var(--secondary-background-color) !important;

export const BlockPubkeyForm: React.FC<BlockPubkeyFormProps> = ({
onSubmit,
disabled,
}) => {
& .ant-card-head {
border-bottom-color: var(--border-base-color) !important;
}
}
`;
const TextArea = styled(Input.TextArea)`
background-color: var(--layout-sider-bg-color) !important;
`;
const InputArea = styled(Input)`
background-color: var(--layout-sider-bg-color) !important;
`;
export const FormItemContainer = styled.div`
width: 100%;
@media screen and (min-width: ${BREAKPOINTS.md}px) {
padding-right: 1.5rem;
}
`;

export const BlockPubkeyForm: React.FC<BlockPubkeyFormProps> = ({ onSubmit, disabled }) => {
const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false);

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

return (
<Card title="Block a Pubkey" size="small">
<Form
form={form}
layout="vertical"
onFinish={handleSubmit}
>
<Form.Item
name="pubkey"
label="Pubkey to block"
rules={[{ validator: validatePubkey }]}
>
<Input placeholder="Enter the 64-character hex pubkey" />
</Form.Item>
<CardRoot title="Block a Pubkey" size="small">
<Form form={form} layout="vertical" onFinish={handleSubmit}>
<FormItemContainer>
<Form.Item name="pubkey" label="Pubkey to block" rules={[{ validator: validatePubkey }]}>
<InputArea placeholder="Enter the 64-character hex pubkey" />
</Form.Item>
</FormItemContainer>

<Form.Item
name="reason"
label="Reason (optional)"
>
<Input.TextArea
placeholder="Enter reason for blocking this pubkey"
rows={2}
/>
</Form.Item>
<FormItemContainer>
<Form.Item name="reason" label="Reason (optional)">
<TextArea placeholder="Enter reason for blocking this pubkey" rows={2} />
</Form.Item>
</FormItemContainer>

<Form.Item>
<Button
type="primary"
htmlType="submit"
icon={<PlusOutlined />}
loading={submitting}
disabled={disabled}
>
<Button type="primary" htmlType="submit" icon={<PlusOutlined />} loading={submitting} disabled={disabled}>
Block Pubkey
</Button>
</Form.Item>
</Form>
</Card>
</CardRoot>
);
};
Loading
Loading