feat/revoke-share #3
@@ -6,7 +6,7 @@ import {
|
|||||||
DialogActions, CircularProgress, Paper, Chip,
|
DialogActions, CircularProgress, Paper, Chip,
|
||||||
Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
|
Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
|
||||||
Switch, FormControlLabel, Divider, List, ListItem, ListItemText, ListItemSecondaryAction,
|
Switch, FormControlLabel, Divider, List, ListItem, ListItemText, ListItemSecondaryAction,
|
||||||
Tabs, Tab, Select, MenuItem, FormControl, InputLabel
|
Select, MenuItem, FormControl, InputLabel
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
@@ -20,7 +20,6 @@ import LockResetIcon from '@mui/icons-material/LockReset';
|
|||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import ShareIcon from '@mui/icons-material/Share';
|
import ShareIcon from '@mui/icons-material/Share';
|
||||||
import GroupAddIcon from '@mui/icons-material/GroupAdd';
|
import GroupAddIcon from '@mui/icons-material/GroupAdd';
|
||||||
import PublicIcon from '@mui/icons-material/Public';
|
|
||||||
import ShieldIcon from '@mui/icons-material/Shield';
|
import ShieldIcon from '@mui/icons-material/Shield';
|
||||||
import GppBadIcon from '@mui/icons-material/GppBad';
|
import GppBadIcon from '@mui/icons-material/GppBad';
|
||||||
import PeopleIcon from '@mui/icons-material/People';
|
import PeopleIcon from '@mui/icons-material/People';
|
||||||
@@ -34,9 +33,8 @@ import NebulaBanner from '../components/NebulaBanner';
|
|||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
const { currentTheme, setTheme } = useAppTheme();
|
const { currentTheme, setTheme } = useAppTheme();
|
||||||
const {
|
const {
|
||||||
accounts, isLoading, isSyncing, serverConfig, addAccount, deleteAccount,
|
accounts, isLoading, isSyncing, serverConfig, deleteAccount,
|
||||||
switchAccount, openSteamLogin, updateServerConfig, loginToServer,
|
switchAccount, openSteamLogin, updateServerConfig, loginToServer, syncNow
|
||||||
getCommunityAccounts, syncNow
|
|
||||||
} = useAccounts();
|
} = useAccounts();
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
@@ -159,6 +157,98 @@ const Dashboard: React.FC = () => {
|
|||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
{/* Settings Dialog */}
|
{/* Settings Dialog */}
|
||||||
|
<Dialog open={isSettingsOpen} onClose={() => setIsSettingsOpen(false)} maxWidth="sm" fullWidth>
|
||||||
|
<DialogTitle sx={{ backgroundColor: 'background.paper', color: 'text.primary' }}>Settings & Customization</DialogTitle>
|
||||||
|
<DialogContent sx={{ backgroundColor: 'background.paper', pt: 2 }}>
|
||||||
|
<Typography variant="subtitle2" gutterBottom sx={{ color: 'primary.main', mt: 1 }}>THEME SELECTION</Typography>
|
||||||
|
<FormControl fullWidth size="small" sx={{ mb: 3 }}>
|
||||||
|
<InputLabel sx={{ color: 'text.secondary' }}>Active Theme</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={currentTheme || 'steam'}
|
||||||
|
label="Active Theme"
|
||||||
|
onChange={(e) => setTheme(e.target.value as ThemeType)}
|
||||||
|
sx={{ bgcolor: 'rgba(0,0,0,0.1)', color: 'text.primary' }}
|
||||||
|
>
|
||||||
|
<MenuItem value="steam">Steam Classic</MenuItem>
|
||||||
|
<MenuItem value="mocha">Catppuccin Mocha</MenuItem>
|
||||||
|
<MenuItem value="latte">Catppuccin Latte</MenuItem>
|
||||||
|
<MenuItem value="nord">Nord Arctic</MenuItem>
|
||||||
|
<MenuItem value="tokyo">Tokyo Night</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<Divider sx={{ my: 2, borderColor: 'divider' }} />
|
||||||
|
|
||||||
|
<Typography variant="subtitle2" gutterBottom sx={{ color: 'primary.main' }}>BACKEND CONFIGURATION</Typography>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
label="Server URL"
|
||||||
|
value={serverUrl}
|
||||||
|
onChange={(e) => setServerUrl(e.target.value)}
|
||||||
|
placeholder="https://ultimate-ban-tracker.narl.io"
|
||||||
|
margin="dense"
|
||||||
|
sx={{ mb: 2 }}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<Button variant="contained" size="small" onClick={saveSettings} sx={{ height: 30 }}>Apply</Button>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Divider sx={{ my: 2, borderColor: 'divider' }} />
|
||||||
|
|
||||||
|
<Typography variant="subtitle2" gutterBottom sx={{ color: 'primary.main' }}>COMMUNITY AUTHENTICATION</Typography>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', p: 2, bgcolor: 'rgba(0,0,0,0.1)', borderRadius: 1 }}>
|
||||||
|
<Box>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{serverConfig?.token ? "Connected to Server" : "Not Authenticated"}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" color="textSecondary">
|
||||||
|
{serverConfig?.token ? "Your accounts can now be shared with others." : "Login to share and sync with your community."}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', gap: 1 }}>
|
||||||
|
{serverConfig?.token && (
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
onClick={() => updateServerConfig({ token: undefined, enabled: false })}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => loginToServer()}
|
||||||
|
disabled={!serverUrl}
|
||||||
|
>
|
||||||
|
{serverConfig?.token ? "Re-Login" : "Login with Steam"}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={serverConfig?.enabled || false}
|
||||||
|
onChange={(e) => updateServerConfig({ enabled: e.target.checked })}
|
||||||
|
disabled={!serverConfig?.token}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Enable Community Sync"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions sx={{ backgroundColor: 'background.paper', p: 2 }}>
|
||||||
|
<Button onClick={() => setIsSettingsOpen(false)} color="inherit" variant="contained">Done</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// --- Sub-Component: AccountRow ---
|
// --- Sub-Component: AccountRow ---
|
||||||
|
|
||||||
@@ -204,7 +294,8 @@ const AccountRow: React.FC<{
|
|||||||
(window as any).electronAPI.getServerUserInfo()
|
(window as any).electronAPI.getServerUserInfo()
|
||||||
]);
|
]);
|
||||||
const filtered = (Array.isArray(users) ? users : []).filter(u =>
|
const filtered = (Array.isArray(users) ? users : []).filter(u =>
|
||||||
u.steamId !== selfInfo.steamId && u.steamId !== account.steamId
|
u.steamId !== selfInfo.steamId &&
|
||||||
|
u.steamId !== account.steamId
|
||||||
);
|
);
|
||||||
setServerUsers(filtered);
|
setServerUsers(filtered);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
@@ -237,9 +328,7 @@ const AccountRow: React.FC<{
|
|||||||
// Primary account check
|
// Primary account check
|
||||||
const isPrimaryAccount = serverConfig?.serverSteamId === account.steamId;
|
const isPrimaryAccount = serverConfig?.serverSteamId === account.steamId;
|
||||||
|
|
||||||
// Refined Shared Logic:
|
// Refined Shared Logic
|
||||||
// 1. It was shared WITH you (starts with shared_)
|
|
||||||
// 2. OR you are the owner but you have shared it with at least one person
|
|
||||||
const isSharedWithYou = account?._id.startsWith('shared_');
|
const isSharedWithYou = account?._id.startsWith('shared_');
|
||||||
const hasSharedMembers = (account as any).sharedWith && (account as any).sharedWith.length > 0;
|
const hasSharedMembers = (account as any).sharedWith && (account as any).sharedWith.length > 0;
|
||||||
const showCommunityIcon = isSharedWithYou || hasSharedMembers;
|
const showCommunityIcon = isSharedWithYou || hasSharedMembers;
|
||||||
|
|||||||
Reference in New Issue
Block a user