338 lines
11 KiB
HTML
338 lines
11 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
|
||
<title>共享空间 — 邀请 / 加入</title>
|
||
<style>
|
||
:root{
|
||
--bg: #f6f7fb;
|
||
--card: #ffffff;
|
||
--muted: #9aa4b2;
|
||
--accent: #5b8cff;
|
||
--danger: #ff6b6b;
|
||
--radius: 12px;
|
||
--gap: 12px;
|
||
--shadow: 0 6px 18px rgba(22,27,40,0.06);
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial;
|
||
}
|
||
|
||
/* Reset / basic */
|
||
*{box-sizing:border-box}
|
||
html,body{height:100%}
|
||
body{
|
||
margin:0;
|
||
background:linear-gradient(180deg, var(--bg), #eef2ff 60%);
|
||
color:#0f1724;
|
||
-webkit-font-smoothing:antialiased;
|
||
-moz-osx-font-smoothing:grayscale;
|
||
padding:16px;
|
||
}
|
||
|
||
/* Container */
|
||
.screen{
|
||
max-width:480px;
|
||
margin:0 auto;
|
||
}
|
||
|
||
header.appbar{
|
||
display:flex;
|
||
align-items:center;
|
||
gap:12px;
|
||
padding:8px 4px;
|
||
margin-bottom:12px;
|
||
}
|
||
.title{
|
||
font-size:18px;
|
||
font-weight:600;
|
||
}
|
||
.subtitle{
|
||
display:block;
|
||
font-size:12px;
|
||
color:var(--muted);
|
||
margin-top:2px;
|
||
}
|
||
|
||
/* Cards */
|
||
.card{
|
||
background:var(--card);
|
||
border-radius:var(--radius);
|
||
box-shadow:var(--shadow);
|
||
padding:14px;
|
||
margin-bottom:var(--gap);
|
||
}
|
||
|
||
/* Invite area */
|
||
.invite-top{
|
||
display:flex;
|
||
gap:12px;
|
||
align-items:center;
|
||
}
|
||
.space-avatar{
|
||
width:56px;height:56px;border-radius:12px;background:linear-gradient(135deg,#7fb6ff,#5b8cff);
|
||
display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:20px;
|
||
}
|
||
.space-info{
|
||
flex:1;
|
||
}
|
||
.space-name{font-weight:600;font-size:16px}
|
||
.space-meta{font-size:12px;color:var(--muted);margin-top:4px}
|
||
|
||
.invite-row{
|
||
margin-top:12px;display:flex;gap:8px;
|
||
}
|
||
.btn{
|
||
flex:1;
|
||
border:0;padding:10px 12px;border-radius:10px;font-weight:600;
|
||
background:var(--accent);color:#fff;cursor:pointer;
|
||
box-shadow:0 6px 12px rgba(91,140,255,0.18);
|
||
}
|
||
.btn.ghost{background:transparent;color:var(--accent);border:1px solid rgba(91,140,255,0.12);box-shadow:none}
|
||
.btn.danger{background:var(--danger);box-shadow:0 6px 12px rgba(255,107,107,0.16)}
|
||
|
||
/* Invite code box */
|
||
.code-box{display:flex;align-items:center;justify-content:space-between;padding:10px;border-radius:10px;background:#f4f7ff;border:1px dashed rgba(91,140,255,0.18)}
|
||
.code-text{font-weight:700;letter-spacing:2px;font-size:16px}
|
||
.code-actions{display:flex;gap:8px}
|
||
|
||
/* Join section */
|
||
.join-input{
|
||
display:flex;gap:8px;margin-top:8px;
|
||
}
|
||
.input{
|
||
flex:1;padding:10px;border-radius:10px;border:1px solid #e6e9ef;background:#fff;
|
||
font-size:14px;
|
||
}
|
||
.help-line{font-size:12px;color:var(--muted);margin-top:8px}
|
||
|
||
/* Recent invites / list */
|
||
.list-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-top:1px solid #f2f4f8}
|
||
.list-left{display:flex;align-items:center;gap:10px}
|
||
.small-avatar{width:36px;height:36px;border-radius:8px;background:#eef4ff;display:flex;align-items:center;justify-content:center;color:#3759c8;font-weight:700}
|
||
.list-title{font-weight:600}
|
||
.list-sub{font-size:12px;color:var(--muted)}
|
||
|
||
/* Modal (simple) */
|
||
.overlay{position:fixed;left:0;right:0;top:0;bottom:0;background:rgba(8,10,15,0.45);display:flex;align-items:center;justify-content:center;padding:20px;z-index:80}
|
||
.modal{width:100%;max-width:420px;border-radius:14px;background:var(--card);padding:16px;box-shadow:var(--shadow)}
|
||
.modal .h1{font-weight:700;margin-bottom:8px}
|
||
.modal .muted{color:var(--muted);font-size:13px;margin-bottom:12px}
|
||
.share-grid{display:flex;gap:8px;flex-wrap:wrap}
|
||
|
||
.share-chip{flex:0 0 30%;min-width:84px;padding:10px;border-radius:10px;background:#f7f9ff;text-align:center;font-size:13px;color:#123;background:linear-gradient(180deg,#fff,#f7f9ff);cursor:pointer}
|
||
.copy-toast{position:fixed;left:50%;transform:translateX(-50%);bottom:22px;padding:8px 14px;background:rgba(0,0,0,0.7);color:#fff;border-radius:20px;font-size:13px;z-index:90}
|
||
|
||
/* Footer hint */
|
||
.hint{font-size:12px;color:var(--muted);text-align:center;margin-top:12px}
|
||
|
||
/* small screens */
|
||
@media (max-width:360px){
|
||
.btn{padding:10px}
|
||
.space-avatar{width:48px;height:48px;font-size:18px}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="screen">
|
||
<header class="appbar">
|
||
<div style="width:44px;"></div>
|
||
<div>
|
||
<div class="title">共享空间</div>
|
||
<div class="subtitle">邀请别人加入你的空间,或输入邀请码加入别人空间</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Invite card -->
|
||
<section class="card">
|
||
<div class="invite-top">
|
||
<div class="space-avatar" id="spaceAvatar">A</div>
|
||
<div class="space-info">
|
||
<div class="space-name" id="spaceName">工作协作空间</div>
|
||
<div class="space-meta">成员 12 • 权限 管理者</div>
|
||
</div>
|
||
<div style="width:68px;text-align:right"><button class="btn ghost" id="manageBtn">管理</button></div>
|
||
</div>
|
||
|
||
<div style="margin-top:14px">
|
||
<div class="code-box" id="codeBox">
|
||
<div class="code-text" id="inviteCode">AB12-CD34</div>
|
||
<div class="code-actions">
|
||
<button class="btn ghost" id="copyBtn">复制</button>
|
||
<button class="btn" id="shareBtn">分享</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="invite-row">
|
||
<button class="btn ghost" id="qrBtn">二维码</button>
|
||
<button class="btn ghost" id="linkBtn">链接</button>
|
||
<button class="btn danger" id="revokeBtn">撤销并重置</button>
|
||
</div>
|
||
</div>
|
||
<div class="hint">邀请码有效期:24小时 · 点击分享可选择渠道</div>
|
||
</section>
|
||
|
||
<!-- Join other -->
|
||
<section class="card" aria-label="加入他人空间">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;">
|
||
<div style="font-weight:700">加入别人的空间</div>
|
||
<div class="list-sub">通过邀请码或扫码加入</div>
|
||
</div>
|
||
|
||
<div class="join-input">
|
||
<input class="input" id="joinInput" placeholder="输入邀请码或链接(例如:AB12-CD34)" />
|
||
<button class="btn" id="joinBtn">加入</button>
|
||
</div>
|
||
<div class="help-line">若对方使用链接邀请,可直接粘贴链接;扫码请使用 App 内相机。</div>
|
||
|
||
<div style="margin-top:12px">
|
||
<div style="font-weight:600;margin-bottom:8px">最近加入的空间</div>
|
||
<div class="list-row">
|
||
<div class="list-left">
|
||
<div class="small-avatar">P</div>
|
||
<div>
|
||
<div class="list-title">产品设计空间</div>
|
||
<div class="list-sub">邀请人:小李 · 2 天前</div>
|
||
</div>
|
||
</div>
|
||
<div style="text-align:right;">
|
||
<div class="list-sub">成员 8</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="list-row">
|
||
<div class="list-left">
|
||
<div class="small-avatar">M</div>
|
||
<div>
|
||
<div class="list-title">市场推广</div>
|
||
<div class="list-sub">邀请人:小王 · 1 周前</div>
|
||
</div>
|
||
</div>
|
||
<div style="text-align:right;">
|
||
<div class="list-sub">成员 20</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- footer actions -->
|
||
<div style="display:flex;gap:8px;margin-top:8px">
|
||
<button class="btn ghost" style="flex:1" id="createSpace">创建新空间</button>
|
||
<button class="btn" style="flex:1" id="explore">发现空间</button>
|
||
</div>
|
||
|
||
<div style="height:40px"></div>
|
||
</div>
|
||
|
||
<!-- Modal markup (hidden initially) -->
|
||
<div id="modalOverlay" class="overlay" style="display:none;">
|
||
<div class="modal" role="dialog" aria-modal="true">
|
||
<div class="h1">分享邀请</div>
|
||
<div class="muted">选择一种方式邀请你的成员</div>
|
||
|
||
<div class="share-grid" style="margin-bottom:12px;">
|
||
<div class="share-chip" data-action="wechat">微信</div>
|
||
<div class="share-chip" data-action="qq">QQ</div>
|
||
<div class="share-chip" data-action="link">复制链接</div>
|
||
<div class="share-chip" data-action="sms">短信</div>
|
||
<div class="share-chip" data-action="email">邮件</div>
|
||
<div class="share-chip" data-action="more">更多</div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:8px;justify-content:flex-end">
|
||
<button class="btn ghost" onclick="closeModal()">取消</button>
|
||
<button class="btn" id="modalShare">分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- toast -->
|
||
<div id="copyToast" class="copy-toast" style="display:none;">已复制到剪贴板</div>
|
||
|
||
<script>
|
||
// demo interactions
|
||
const inviteCodeEl = document.getElementById('inviteCode');
|
||
const copyBtn = document.getElementById('copyBtn');
|
||
const shareBtn = document.getElementById('shareBtn');
|
||
const modal = document.getElementById('modalOverlay');
|
||
const copyToast = document.getElementById('copyToast');
|
||
const joinInput = document.getElementById('joinInput');
|
||
const joinBtn = document.getElementById('joinBtn');
|
||
|
||
// copy code
|
||
copyBtn.addEventListener('click', async () => {
|
||
const code = inviteCodeEl.textContent.trim();
|
||
try {
|
||
await navigator.clipboard.writeText(code);
|
||
showToast('已复制邀请码');
|
||
} catch (e) {
|
||
showToast('复制失败,请手动复制');
|
||
}
|
||
});
|
||
|
||
// open share modal
|
||
shareBtn.addEventListener('click', () => openModal());
|
||
|
||
document.getElementById('qrBtn').addEventListener('click', ()=> {
|
||
alert('打开二维码生成器(示例占位)');
|
||
});
|
||
document.getElementById('linkBtn').addEventListener('click', ()=> {
|
||
alert('打开链接分享(示例占位)');
|
||
});
|
||
document.getElementById('revokeBtn').addEventListener('click', ()=> {
|
||
const newCode = randomCode();
|
||
inviteCodeEl.textContent = newCode;
|
||
showToast('邀请码已重置');
|
||
});
|
||
|
||
// join
|
||
joinBtn.addEventListener('click', ()=> {
|
||
const v = (joinInput.value || '').trim();
|
||
if (!v) return showToast('请输入邀请码或链接');
|
||
// 简单验证格式示例
|
||
const matched = /^[A-Z0-9]{2,}-[A-Z0-9]{2,}$/.test(v) || v.includes('http');
|
||
if (!matched) return showToast('邀请码格式不正确');
|
||
showToast('加入请求已发送');
|
||
// TODO: 调用后端 API 加入空间
|
||
});
|
||
|
||
// modal actions
|
||
function openModal(){ modal.style.display='flex'; }
|
||
function closeModal(){ modal.style.display='none'; }
|
||
|
||
document.getElementById('modalShare').addEventListener('click', ()=>{
|
||
// 示例:复制链接并关闭
|
||
const fakeLink = location.href + '?invite=' + inviteCodeEl.textContent.trim();
|
||
navigator.clipboard.writeText(fakeLink).catch(()=>{});
|
||
showToast('邀请链接已复制');
|
||
closeModal();
|
||
});
|
||
|
||
// copy chips
|
||
document.querySelectorAll('.share-chip').forEach(el=>{
|
||
el.addEventListener('click', ()=> {
|
||
const action = el.getAttribute('data-action');
|
||
if (action === 'link') {
|
||
const fakeLink = location.href + '?invite=' + inviteCodeEl.textContent.trim();
|
||
navigator.clipboard.writeText(fakeLink).then(()=> showToast('链接已复制'));
|
||
} else {
|
||
showToast('已选择:' + action);
|
||
}
|
||
})
|
||
});
|
||
|
||
// small utilities
|
||
function showToast(text){
|
||
copyToast.textContent = text;
|
||
copyToast.style.display = 'block';
|
||
setTimeout(()=> copyToast.style.display='none', 1500);
|
||
}
|
||
|
||
function randomCode(){
|
||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||
const pick = (n)=> Array.from({length:n}).map(()=>chars[Math.floor(Math.random()*chars.length)]).join('');
|
||
return pick(2)+'-'+pick(4);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|