Files
2026-07-16 05:48:12 -05:00

297 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Compose & preview · Portal · MKDRealtor.com</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Work+Sans:300,400,500,700%7CPoppins:400,600,700">
<link rel="stylesheet" href="proposal.css">
</head>
<body class="portal">
<div class="proposal-banner">
<div><span class="tag">Proposal mockup</span> &nbsp; MKDRealtor.com — UX examples (not production)</div>
<div><a href="index.html">All screens</a></div>
</div>
<div class="portal-shell">
<aside class="portal-sidebar">
<a class="portal-brand" href="portal-dashboard.html"><img src="brand/exit_logo.png" alt="EXIT Realty"><span>MKDRealtor.com</span></a>
<nav class="portal-nav">
<div class="nav-section">Overview</div>
<a class="" href="portal-dashboard.html">Dashboard</a>
<a class="" href="portal-leads.html">Leads</a>
<a class="" href="portal-analytics.html">Analytics</a>
<div class="nav-section">Outreach</div>
<a class="" href="portal-contacts.html">Mailing list</a>
<a class="" href="portal-campaign.html">Campaigns</a>
<a class="" href="portal-postcard-designer.html">Postcard design</a>
<div class="nav-section">Social</div>
<a class="active" href="portal-social.html">Compose & preview</a>
<a class="" href="portal-social-accounts.html">Accounts</a>
</nav>
</aside>
<div class="portal-main">
<div class="portal-topbar">
<h1>Compose & preview</h1>
<div class="portal-user">Signed in as <strong>Monica Dhillon</strong> · <a href="portal-login.html" style="color:#00626c">Sign out</a></div>
</div>
<div class="portal-content">
<div class="proposal-note"><strong>UX note:</strong> AI chat helps draft captions (tone, length, hashtags). Insert or replace into the composer — live FB / IG / LinkedIn previews update instantly.</div>
<div class="auth-alert" id="li-warn">
<strong>LinkedIn needs re-auth.</strong> Token expired —
<a href="portal-social-accounts.html">Re-authorize in Accounts</a> before scheduling to LinkedIn.
</div>
<div class="designer-layout with-ai">
<div class="designer-controls">
<div class="panel">
<div class="panel-h"><h2>Compose</h2><a class="btn btn-sm btn-ghost" href="portal-social-accounts.html">Manage accounts</a></div>
<div class="panel-b form-grid">
<div class="field"><label>Caption</label>
<textarea id="soc-caption" style="min-height:130px" oninput="syncSocial()">Open house this Saturday 111 at 412 Willow Lane. Quiet street, updated kitchen, walkable to Oakridge. DM or text me for details.
#JustListed #OpenHouse</textarea>
<div class="hint"><span id="char-count">0</span> characters · IG soft limit ~2,200</div>
</div>
<div class="field"><label>Media</label>
<select id="soc-media" onchange="syncSocial()">
<option value="images/grid-layout-1-370x256.jpg">Willow Lane exterior</option>
<option value="images/grid-layout-2-370x256.jpg">Kitchen</option>
<option value="images/grid-layout-3-370x256.jpg">Living room</option>
<option value="">Text only (FB / LI)</option>
</select>
</div>
<div class="field"><label>Platforms</label>
<div class="platform-toggles">
<label class="toggle-pill"><input type="checkbox" id="plat-fb" checked onchange="syncSocial()"> Facebook</label>
<label class="toggle-pill"><input type="checkbox" id="plat-ig" checked onchange="syncSocial()"> Instagram</label>
<label class="toggle-pill warn"><input type="checkbox" id="plat-li" onchange="syncSocial()"> LinkedIn <span class="muted">(re-auth)</span></label>
</div>
</div>
<div class="form-grid cols-2">
<div class="field"><label>Publish</label>
<select id="soc-when-mode"><option>Schedule</option><option>Publish now</option></select>
</div>
<div class="field"><label>When</label><input type="datetime-local" value="2026-07-16T09:00"></div>
</div>
<div class="field"><label>Preview as</label>
<div class="channel-tabs" style="margin:0">
<a href="#" class="active" id="prev-fb" onclick="setPreview('fb');return false">Facebook</a>
<a href="#" id="prev-ig" onclick="setPreview('ig');return false">Instagram</a>
<a href="#" id="prev-li" onclick="setPreview('li');return false">LinkedIn</a>
</div>
</div>
<button class="btn btn-primary" type="button" onclick="alert('Mockup: SocialPost + SocialPostTargets enqueued')">Schedule to selected platforms</button>
</div>
</div>
</div>
<div class="ai-assist-col">
<div class="ai-chat">
<div class="ai-chat-h">
<h2>AI post assistant</h2>
<span class="ai-pill">Beta mockup</span>
</div>
<div class="ai-chat-messages" id="ai-messages">
<div class="ai-msg bot">
<div class="who">Assistant</div>
<div class="bubble">
I can draft or refine captions for Facebook, Instagram, and LinkedIn.
Tell me the listing, tone (warm / bold / luxury), and any must-include details —
or tap a quick prompt below.
</div>
</div>
</div>
<div class="ai-chat-prompts">
<button type="button" class="chip" onclick="sendPrompt('Write an open-house post for 412 Willow Lane')">Open house draft</button>
<button type="button" class="chip" onclick="sendPrompt('Make my caption shorter for Instagram')">Shorter for IG</button>
<button type="button" class="chip" onclick="sendPrompt('Rewrite in a warmer, neighborly tone')">Warmer tone</button>
<button type="button" class="chip" onclick="sendPrompt('Add 4 relevant hashtags')">Add hashtags</button>
<button type="button" class="chip" onclick="sendPrompt('Make a LinkedIn-friendly professional version')">LinkedIn version</button>
</div>
<div class="ai-chat-input">
<textarea id="ai-input" placeholder="Ask for a draft, rewrite, or hashtags…" rows="2"
onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendChat();}"></textarea>
<button class="btn btn-primary" type="button" onclick="sendChat()">Send</button>
</div>
</div>
</div>
<div class="designer-preview-col">
<div class="panel">
<div class="panel-h"><h2>Live post preview</h2><span class="muted" style="font-size:12px" id="prev-label">Facebook</span></div>
<div class="panel-b" style="background:#e8edf3;display:flex;justify-content:center;padding:24px">
<div class="social-phone" id="preview-fb">
<div class="soc-header">
<div class="soc-avatar">MR</div>
<div>
<div class="soc-name">Monica Dhillon · MKDRealtor.com</div>
<div class="soc-meta">Sponsored · Just now · 🌐</div>
</div>
</div>
<div class="soc-caption" id="fb-caption"></div>
<div class="soc-image" id="fb-image"></div>
<div class="soc-actions">Like · Comment · Share</div>
</div>
<div class="social-phone ig" id="preview-ig" style="display:none">
<div class="soc-header">
<div class="soc-avatar round">MR</div>
<div>
<div class="soc-name">monicadhillonhomes</div>
<div class="soc-meta">Metro Area</div>
</div>
<div class="soc-more">•••</div>
</div>
<div class="soc-image square" id="ig-image"></div>
<div class="soc-actions ig-act">&nbsp; 💬 &nbsp;</div>
<div class="soc-caption"><strong>monicadhillonhomes</strong> <span id="ig-caption"></span></div>
</div>
<div class="social-phone li" id="preview-li" style="display:none">
<div class="soc-header">
<div class="soc-avatar sq">MR</div>
<div>
<div class="soc-name">Monica Dhillon</div>
<div class="soc-meta">Realtor · 1st · Just now</div>
</div>
</div>
<div class="soc-caption" id="li-caption"></div>
<div class="soc-image" id="li-image"></div>
<div class="soc-actions">Like · Comment · Repost · Send</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-h"><h2>Scheduled</h2></div>
<div class="panel-b" style="padding:0">
<table class="table">
<thead><tr><th>Post</th><th>Platforms</th><th>Status</th></tr></thead>
<tbody>
<tr><td>Open house Willow Lane</td><td>FB · IG</td><td><span class="badge badge-scheduled">Scheduled</span></td></tr>
<tr><td>Just sold — Birch Ave</td><td>FB · IG · LI</td><td><span class="badge badge-delivered">Published</span></td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let previewPlat = 'fb';
let lastDraft = '';
function setPreview(p) {
previewPlat = p;
['fb','ig','li'].forEach(x => {
document.getElementById('preview-' + x).style.display = x === p ? 'block' : 'none';
document.getElementById('prev-' + x).classList.toggle('active', x === p);
});
document.getElementById('prev-label').textContent = ({fb:'Facebook',ig:'Instagram',li:'LinkedIn'})[p];
}
function syncSocial() {
const cap = document.getElementById('soc-caption').value;
const media = document.getElementById('soc-media').value;
document.getElementById('char-count').textContent = cap.length;
document.getElementById('fb-caption').textContent = cap;
document.getElementById('ig-caption').textContent = cap;
document.getElementById('li-caption').textContent = cap;
['fb','ig','li'].forEach(x => {
const el = document.getElementById(x + '-image');
if (!media) { el.style.display = 'none'; }
else { el.style.display = 'block'; el.style.backgroundImage = 'url(' + media + ')'; }
});
document.getElementById('li-warn').style.display = document.getElementById('plat-li').checked ? 'block' : 'none';
}
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
}
function appendMsg(role, html) {
const root = document.getElementById('ai-messages');
const div = document.createElement('div');
div.className = 'ai-msg ' + role;
div.innerHTML =
'<div class="who">' + (role === 'user' ? 'You' : 'Assistant') + '</div>' +
'<div class="bubble">' + html + '</div>';
root.appendChild(div);
root.scrollTop = root.scrollHeight;
}
function draftActions(draft) {
lastDraft = draft;
const id = 'draft-' + Date.now();
return (
'<div class="ai-draft" id="' + id + '">' + escapeHtml(draft) + '</div>' +
'<div class="ai-msg-actions">' +
'<button type="button" class="btn btn-sm btn-primary" onclick="insertDraft(false)">Replace caption</button>' +
'<button type="button" class="btn btn-sm btn-ghost" onclick="insertDraft(true)">Append</button>' +
'</div>'
);
}
function insertDraft(append) {
const ta = document.getElementById('soc-caption');
if (append && ta.value.trim()) ta.value = ta.value.replace(/\s*$/, '') + '\n\n' + lastDraft;
else ta.value = lastDraft;
syncSocial();
}
function inventReply(prompt, current) {
const p = prompt.toLowerCase();
if (p.includes('shorter') || p.includes('instagram')) {
return 'Open house Sat 111 · 412 Willow Lane\nUpdated kitchen, quiet street, walk to Oakridge.\nDM for details 🏡\n\n#JustListed #OpenHouse #WillowLane';
}
if (p.includes('warm') || p.includes('neighbor')) {
return 'I\'d love to show you around this Saturday.\n\n412 Willow Lane is open 111 — quiet street, bright kitchen, and an easy walk to Oakridge schools. Come say hi, no pressure.\n\nText me anytime if you want a private look first.';
}
if (p.includes('hashtag')) {
const base = current.trim() || 'Just listed — 412 Willow Lane. Open house Saturday 111.';
return base.replace(/\s*#\S+/g, '').trim() + '\n\n#JustListed #OpenHouse #RealEstate #HomeTour';
}
if (p.includes('linkedin') || p.includes('professional')) {
return 'Hosting an open house this Saturday, 111, at 412 Willow Lane.\n\nUpdated kitchen, walkable to Oakridge schools, asking $449,000. Happy to arrange a private showing for clients who can\'t make the window.\n\n#RealEstate #OpenHouse';
}
if (p.includes('open house') || p.includes('willow') || p.includes('draft')) {
return 'Open house this Saturday 111 at 412 Willow Lane.\n\nQuiet street · updated kitchen · walkable to Oakridge.\nDM or text me for details — hope to see you there!\n\n#JustListed #OpenHouse';
}
if (p.includes('rewrite') || p.includes('improve') || current.trim()) {
return 'Just listed: 412 Willow Lane.\n\nOpen Saturday 111. Updated kitchen, quiet street, walkable to Oakridge schools. Asking $449,000.\n\nMessage me for a private showing.\n\n#JustListed #OpenHouse';
}
return 'Tell me the address, price band, and vibe (warm / bold / luxury) and I\'ll draft a caption you can drop straight into the composer.';
}
function respond(prompt) {
const current = document.getElementById('soc-caption').value;
const draft = inventReply(prompt, current);
const needsDraft = !/tell me the address/i.test(draft);
const body = needsDraft
? 'Here\'s a draft you can use:' + draftActions(draft)
: escapeHtml(draft);
appendMsg('bot', body);
}
function sendPrompt(text) {
document.getElementById('ai-input').value = text;
sendChat();
}
function sendChat() {
const input = document.getElementById('ai-input');
const text = input.value.trim();
if (!text) return;
appendMsg('user', escapeHtml(text));
input.value = '';
setTimeout(() => respond(text), 350);
}
syncSocial();
</script>
</body>
</html>