ui fix
This commit is contained in:
@@ -15,7 +15,7 @@ interface NotificationDetails {
|
||||
}
|
||||
|
||||
const NotificationsTab = () => {
|
||||
const [filter, setFilter] = useState<'all' | 'error' | 'warning'>('all');
|
||||
const [filter, setFilter] = useState<'all' | 'error' | 'warning' | 'update'>('all');
|
||||
const logs = useStore(logStore.logs);
|
||||
|
||||
const handleClearNotifications = () => {
|
||||
@@ -29,13 +29,44 @@ const NotificationsTab = () => {
|
||||
const filteredLogs = Object.values(logs)
|
||||
.filter((log) => {
|
||||
if (filter === 'all') {
|
||||
return log.level === 'error' || log.level === 'warning';
|
||||
return log.level === 'error' || log.level === 'warning' || log.details?.type === 'update';
|
||||
}
|
||||
|
||||
if (filter === 'update') {
|
||||
return log.details?.type === 'update';
|
||||
}
|
||||
|
||||
return log.level === filter;
|
||||
})
|
||||
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
||||
|
||||
const getNotificationStyle = (log: (typeof filteredLogs)[0]) => {
|
||||
if (log.details?.type === 'update') {
|
||||
return {
|
||||
border: 'border-purple-200 dark:border-purple-900/50',
|
||||
bg: 'bg-purple-50 dark:bg-purple-900/20',
|
||||
icon: 'i-ph:arrow-circle-up text-purple-600 dark:text-purple-400',
|
||||
text: 'text-purple-900 dark:text-purple-300',
|
||||
};
|
||||
}
|
||||
|
||||
if (log.level === 'error') {
|
||||
return {
|
||||
border: 'border-red-200 dark:border-red-900/50',
|
||||
bg: 'bg-red-50 dark:bg-red-900/20',
|
||||
icon: 'i-ph:warning-circle text-red-600 dark:text-red-400',
|
||||
text: 'text-red-900 dark:text-red-300',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
border: 'border-yellow-200 dark:border-yellow-900/50',
|
||||
bg: 'bg-yellow-50 dark:bg-yellow-900/20',
|
||||
icon: 'i-ph:warning text-yellow-600 dark:text-yellow-400',
|
||||
text: 'text-yellow-900 dark:text-yellow-300',
|
||||
};
|
||||
};
|
||||
|
||||
const renderNotificationDetails = (details: NotificationDetails) => {
|
||||
if (details.type === 'update') {
|
||||
return (
|
||||
@@ -48,7 +79,7 @@ const NotificationsTab = () => {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => details.updateUrl && handleUpdateAction(details.updateUrl)}
|
||||
className="mt-2 inline-flex items-center gap-2 rounded-md bg-blue-50 px-3 py-1.5 text-sm font-medium text-blue-600 hover:bg-blue-100 dark:bg-blue-900/20 dark:text-blue-400 dark:hover:bg-blue-900/30"
|
||||
className="mt-2 inline-flex items-center gap-2 rounded-md bg-purple-50 px-3 py-1.5 text-sm font-medium text-purple-600 hover:bg-purple-100 dark:bg-purple-900/20 dark:text-purple-400 dark:hover:bg-purple-900/30"
|
||||
>
|
||||
<span className="i-ph:git-branch text-lg" />
|
||||
View Changes
|
||||
@@ -66,10 +97,11 @@ const NotificationsTab = () => {
|
||||
<div className="flex items-center gap-2">
|
||||
<select
|
||||
value={filter}
|
||||
onChange={(e) => setFilter(e.target.value as 'all' | 'error' | 'warning')}
|
||||
onChange={(e) => setFilter(e.target.value as 'all' | 'error' | 'warning' | 'update')}
|
||||
className="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
||||
>
|
||||
<option value="all">All Notifications</option>
|
||||
<option value="update">Updates</option>
|
||||
<option value="error">Errors</option>
|
||||
<option value="warning">Warnings</option>
|
||||
</select>
|
||||
@@ -92,48 +124,30 @@ const NotificationsTab = () => {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
filteredLogs.map((log) => (
|
||||
<motion.div
|
||||
key={log.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className={classNames(
|
||||
'flex flex-col gap-2 rounded-lg border p-4',
|
||||
log.level === 'error'
|
||||
? 'border-red-200 bg-red-50 dark:border-red-900/50 dark:bg-red-900/20'
|
||||
: 'border-yellow-200 bg-yellow-50 dark:border-yellow-900/50 dark:bg-yellow-900/20',
|
||||
)}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span
|
||||
className={classNames(
|
||||
'text-lg',
|
||||
log.level === 'error'
|
||||
? 'i-ph:warning-circle text-red-600 dark:text-red-400'
|
||||
: 'i-ph:warning text-yellow-600 dark:text-yellow-400',
|
||||
)}
|
||||
/>
|
||||
<div>
|
||||
<h3
|
||||
className={classNames(
|
||||
'text-sm font-medium',
|
||||
log.level === 'error'
|
||||
? 'text-red-900 dark:text-red-300'
|
||||
: 'text-yellow-900 dark:text-yellow-300',
|
||||
)}
|
||||
>
|
||||
{log.message}
|
||||
</h3>
|
||||
{log.details && renderNotificationDetails(log.details as NotificationDetails)}
|
||||
filteredLogs.map((log) => {
|
||||
const style = getNotificationStyle(log);
|
||||
return (
|
||||
<motion.div
|
||||
key={log.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className={classNames('flex flex-col gap-2 rounded-lg border p-4', style.border, style.bg)}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className={classNames('text-lg', style.icon)} />
|
||||
<div>
|
||||
<h3 className={classNames('text-sm font-medium', style.text)}>{log.message}</h3>
|
||||
{log.details && renderNotificationDetails(log.details as NotificationDetails)}
|
||||
</div>
|
||||
</div>
|
||||
<time className="shrink-0 text-xs text-gray-500 dark:text-gray-400">
|
||||
{formatDistanceToNow(new Date(log.timestamp), { addSuffix: true })}
|
||||
</time>
|
||||
</div>
|
||||
<time className="shrink-0 text-xs text-gray-500 dark:text-gray-400">
|
||||
{formatDistanceToNow(new Date(log.timestamp), { addSuffix: true })}
|
||||
</time>
|
||||
</div>
|
||||
</motion.div>
|
||||
))
|
||||
</motion.div>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user