fix: 公告弹窗改为 CSS Module 规范
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 10m8s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 10m8s
inline style 改为 CSS Module,z-index/圆角/关闭按钮与其他弹窗统一 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0ab5523ed1
commit
f4255a04ee
86
web/src/components/AnnouncementModal.module.css
Normal file
86
web/src/components/AnnouncementModal.module.css
Normal file
@ -0,0 +1,86 @@
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 300;
|
||||
}
|
||||
|
||||
.modal {
|
||||
background: #16161e;
|
||||
border: 1px solid var(--color-border-card);
|
||||
border-radius: var(--radius-card);
|
||||
max-width: 520px;
|
||||
width: 90vw;
|
||||
max-height: 75vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px 32px 12px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.closeBtn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
|
||||
.closeBtn:hover {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
color: var(--color-text-primary);
|
||||
word-break: break-word;
|
||||
padding: 16px 40px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 16px 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.confirmBtn {
|
||||
padding: 8px 32px;
|
||||
background: var(--color-primary);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
.confirmBtn:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { videoApi } from '../lib/api';
|
||||
import styles from './AnnouncementModal.module.css';
|
||||
|
||||
interface Props {
|
||||
/** If true, force show even if already read (for manual open) */
|
||||
@ -31,51 +32,23 @@ export function AnnouncementModal({ forceOpen, onClose }: Props) {
|
||||
if (!visible || !content) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed', inset: 0, zIndex: 400,
|
||||
background: 'rgba(0, 0, 0, 0.6)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
}}
|
||||
onMouseDown={(e) => { if (e.target === e.currentTarget) handleClose(); }}
|
||||
>
|
||||
<div style={{
|
||||
background: '#16161e', border: '1px solid var(--color-border-card)',
|
||||
borderRadius: 12, padding: '28px 32px', maxWidth: 520, width: '90vw',
|
||||
maxHeight: '70vh', overflowY: 'auto',
|
||||
scrollbarWidth: 'none',
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex', justifyContent: 'space-between', alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
}}>
|
||||
<span style={{ fontSize: 16, fontWeight: 600, color: 'var(--color-text-primary)' }}>
|
||||
📢 公告
|
||||
</span>
|
||||
<button
|
||||
onClick={handleClose}
|
||||
style={{
|
||||
background: 'none', border: 'none', color: 'var(--color-text-secondary)',
|
||||
cursor: 'pointer', fontSize: 18, padding: 4,
|
||||
}}
|
||||
>✕</button>
|
||||
<div className={styles.overlay} onMouseDown={(e) => { if (e.target === e.currentTarget) handleClose(); }}>
|
||||
<div className={styles.modal}>
|
||||
<div className={styles.header}>
|
||||
<span className={styles.title}>公告</span>
|
||||
<button className={styles.closeBtn} onClick={handleClose}>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14, lineHeight: 1.8, color: 'var(--color-text-primary)',
|
||||
wordBreak: 'break-word', padding: '0 8px',
|
||||
}}
|
||||
className={styles.content}
|
||||
dangerouslySetInnerHTML={{ __html: `<style>li{margin-left:16px}</style>${content}` }}
|
||||
/>
|
||||
<div style={{ textAlign: 'center', marginTop: 20 }}>
|
||||
<button
|
||||
onClick={handleClose}
|
||||
style={{
|
||||
padding: '8px 32px', background: 'var(--color-primary)',
|
||||
border: 'none', borderRadius: 8, color: '#fff', fontSize: 14,
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<div className={styles.footer}>
|
||||
<button className={styles.confirmBtn} onClick={handleClose}>
|
||||
我知道了
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user