refactor: 优化会议预览页面的密码输入界面和样式
- 更新密码提示和占位符文本 - 重构密码输入界面布局和样式 - 添加背景动画和视觉效果 - 优化移动端显示dev_na
parent
a49888587f
commit
3469884bca
|
|
@ -614,6 +614,189 @@
|
||||||
background: #eef1ff;
|
background: #eef1ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Password Gate Overhaul --- */
|
||||||
|
.is-password-gate {
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-gate-background {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blob {
|
||||||
|
position: absolute;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.4;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: blob-float 20s infinite alternate cubic-bezier(0.45, 0.05, 0.55, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blob-1 {
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
background: #5f51ff;
|
||||||
|
top: -100px;
|
||||||
|
left: -100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blob-2 {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
background: #6c8cff;
|
||||||
|
bottom: -50px;
|
||||||
|
right: -50px;
|
||||||
|
animation-delay: -5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blob-3 {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: #8e84ff;
|
||||||
|
top: 40%;
|
||||||
|
left: 30%;
|
||||||
|
animation-delay: -10s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blob-float {
|
||||||
|
0% { transform: translate(0, 0) scale(1) rotate(0deg); }
|
||||||
|
33% { transform: translate(30px, 50px) scale(1.1) rotate(10deg); }
|
||||||
|
66% { transform: translate(-20px, 20px) scale(0.9) rotate(-10deg); }
|
||||||
|
100% { transform: translate(0, 0) scale(1) rotate(0deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-password-gate .meeting-preview-shell {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 480px;
|
||||||
|
padding: 24px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-preview-password-card {
|
||||||
|
background: rgba(255, 255, 255, 0.85);
|
||||||
|
backdrop-filter: blur(32px) saturate(200%);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||||
|
border-radius: 32px;
|
||||||
|
padding: 48px 40px;
|
||||||
|
box-shadow:
|
||||||
|
0 40px 100px -20px rgba(95, 81, 255, 0.15),
|
||||||
|
0 0 0 1px rgba(95, 81, 255, 0.05);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-card-header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-icon-wrapper {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
background: var(--primary-gradient);
|
||||||
|
color: white;
|
||||||
|
font-size: 28px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 20px;
|
||||||
|
margin: 0 auto 24px;
|
||||||
|
box-shadow: 0 12px 24px rgba(95, 81, 255, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-card-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--text-main);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-card-subtitle {
|
||||||
|
font-size: 15px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
max-width: 320px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-card-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modern-password-input {
|
||||||
|
border-radius: 16px !important;
|
||||||
|
border: 2px solid rgba(228, 232, 245, 0.8) !important;
|
||||||
|
padding: 12px 16px !important;
|
||||||
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modern-password-input:focus,
|
||||||
|
.modern-password-input-focused {
|
||||||
|
border-color: var(--primary-blue) !important;
|
||||||
|
box-shadow: 0 0 0 4px rgba(95, 81, 255, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-submit-btn {
|
||||||
|
height: 56px !important;
|
||||||
|
border-radius: 16px !important;
|
||||||
|
font-size: 16px !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
background: var(--primary-gradient) !important;
|
||||||
|
border: none !important;
|
||||||
|
box-shadow: 0 12px 24px rgba(95, 81, 255, 0.2) !important;
|
||||||
|
transition: all 0.3s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-submit-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 16px 32px rgba(95, 81, 255, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-error-message {
|
||||||
|
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shake {
|
||||||
|
10%, 90% { transform: translate3d(-1px, 0, 0); }
|
||||||
|
20%, 80% { transform: translate3d(2px, 0, 0); }
|
||||||
|
30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
|
||||||
|
40%, 60% { transform: translate3d(4px, 0, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-gate-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 32px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-disclaimer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.meeting-preview-password-card {
|
||||||
|
padding: 40px 24px;
|
||||||
|
border-radius: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Mobile Optimizations --- */
|
/* --- Mobile Optimizations --- */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.meeting-preview-transcript-list {
|
.meeting-preview-transcript-list {
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ const TEXT = {
|
||||||
shareFailed: "分享失败,请先复制链接",
|
shareFailed: "分享失败,请先复制链接",
|
||||||
accessCheck: "访问校验",
|
accessCheck: "访问校验",
|
||||||
passwordRequired: "该会议需要访问密码",
|
passwordRequired: "该会议需要访问密码",
|
||||||
passwordHint: "请输入会议的 access_password 后继续访问预览内容。",
|
passwordHint: "请输入会议的 访问密码 后继续访问预览内容。",
|
||||||
passwordPlaceholder: "请输入 access_password",
|
passwordPlaceholder: "请输入 访问密码",
|
||||||
openPreview: "进入预览",
|
openPreview: "进入预览",
|
||||||
invalidPassword: "访问密码错误",
|
invalidPassword: "访问密码错误",
|
||||||
basicInfo: "基本信息",
|
basicInfo: "基本信息",
|
||||||
|
|
@ -603,34 +603,60 @@ export default function MeetingPreview() {
|
||||||
|
|
||||||
if (passwordRequired && !passwordVerified) {
|
if (passwordRequired && !passwordVerified) {
|
||||||
return (
|
return (
|
||||||
<div className="meeting-preview-page">
|
<div className="meeting-preview-page is-password-gate">
|
||||||
<div className="meeting-preview-shell meeting-preview-empty">
|
<div className="password-gate-background">
|
||||||
<div className="meeting-preview-card meeting-preview-section meeting-preview-password-gate">
|
<div className="bg-blob bg-blob-1" />
|
||||||
<div className="meeting-preview-section-header">
|
<div className="bg-blob bg-blob-2" />
|
||||||
<div>
|
<div className="bg-blob bg-blob-3" />
|
||||||
<div className="meeting-preview-section-kicker">
|
</div>
|
||||||
|
|
||||||
|
<div className="meeting-preview-shell">
|
||||||
|
<div className="meeting-preview-password-card">
|
||||||
|
<div className="password-card-header">
|
||||||
|
<div className="password-icon-wrapper">
|
||||||
<LockOutlined />
|
<LockOutlined />
|
||||||
{TEXT.accessCheck}
|
|
||||||
</div>
|
|
||||||
<h2 className="meeting-preview-section-title">{TEXT.passwordRequired}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h1 className="password-card-title">{TEXT.passwordRequired}</h1>
|
||||||
|
<p className="password-card-subtitle">{TEXT.passwordHint}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="meeting-preview-subtitle">{TEXT.passwordHint}</p>
|
<div className="password-card-form">
|
||||||
|
<div className="password-input-wrapper">
|
||||||
<div className="meeting-preview-password-form">
|
|
||||||
<Input.Password
|
<Input.Password
|
||||||
|
size="large"
|
||||||
value={accessPassword}
|
value={accessPassword}
|
||||||
placeholder={TEXT.passwordPlaceholder}
|
placeholder={TEXT.passwordPlaceholder}
|
||||||
onChange={(event) => setAccessPassword(event.target.value)}
|
onChange={(event) => setAccessPassword(event.target.value)}
|
||||||
onPressEnter={handlePasswordSubmit}
|
onPressEnter={handlePasswordSubmit}
|
||||||
|
prefix={<LockOutlined style={{ color: "var(--text-secondary)" }} />}
|
||||||
|
className="modern-password-input"
|
||||||
/>
|
/>
|
||||||
<Button type="primary" onClick={handlePasswordSubmit} loading={loading} disabled={!accessPassword.trim()}>
|
</div>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
onClick={handlePasswordSubmit}
|
||||||
|
loading={loading}
|
||||||
|
disabled={!accessPassword.trim()}
|
||||||
|
className="password-submit-btn"
|
||||||
|
block
|
||||||
|
>
|
||||||
{TEXT.openPreview}
|
{TEXT.openPreview}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{passwordError ? <Alert type="error" showIcon message={passwordError} /> : null}
|
{passwordError && (
|
||||||
|
<div className="password-error-message">
|
||||||
|
<Alert type="error" showIcon message={passwordError} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="password-gate-footer">
|
||||||
|
<div className="footer-disclaimer">
|
||||||
|
<RobotOutlined />
|
||||||
|
<span>Secure Access • Powered by iMeeting AI</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue