feat: AI 업셀링 CRM - Clawdbot Gateway 기반 맞춤 추천 시스템
키오스크 적립 시 Clawdbot Gateway(Claude Max)를 통해 구매 이력 기반 맞춤 제품 추천을 생성하고, 마이페이지 방문 시 바텀시트 팝업으로 표시. - ai_recommendations SQLite 테이블 추가 (스키마 + 마이그레이션) - clawdbot_client.py: Gateway WebSocket 프로토콜 v3 Python 클라이언트 - app.py: 추천 생성 + GET/POST API 엔드포인트 - my_page.html: 바텀시트 UI (슬라이드업 애니메이션, 1.5초 후 자동 표시) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -392,6 +392,57 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- AI 추천 바텀시트 -->
|
||||
<div id="rec-sheet" style="display:none;">
|
||||
<div id="rec-backdrop" style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.3);z-index:999;animation:recFadeIn .3s ease;"></div>
|
||||
<div id="rec-content" style="position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:420px;background:#fff;border-radius:24px 24px 0 0;padding:12px 24px 32px;box-shadow:0 -8px 32px rgba(0,0,0,0.12);z-index:1000;animation:recSlideUp .4s cubic-bezier(.16,1,.3,1);">
|
||||
<div style="width:40px;height:4px;background:#dee2e6;border-radius:2px;margin:0 auto 20px;"></div>
|
||||
<div style="text-align:center;padding:8px 0 20px;">
|
||||
<div style="font-size:48px;margin-bottom:16px;">💊</div>
|
||||
<div id="rec-message" style="color:#343a40;font-size:16px;font-weight:500;line-height:1.6;letter-spacing:-0.3px;margin-bottom:16px;"></div>
|
||||
<div id="rec-product" style="display:inline-block;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;font-size:14px;font-weight:600;padding:8px 20px;border-radius:20px;letter-spacing:-0.2px;"></div>
|
||||
</div>
|
||||
<div style="display:flex;gap:12px;padding-bottom:env(safe-area-inset-bottom,0);">
|
||||
<button onclick="dismissRec()" style="flex:1;padding:14px;border:1px solid #dee2e6;border-radius:14px;background:#fff;color:#868e96;font-size:15px;font-weight:600;cursor:pointer;font-family:inherit;">다음에요</button>
|
||||
<button onclick="dismissRec()" style="flex:2;padding:14px;border:none;border-radius:14px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;font-size:15px;font-weight:600;cursor:pointer;font-family:inherit;">관심있어요!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
@keyframes recFadeIn { from{opacity:0} to{opacity:1} }
|
||||
@keyframes recSlideUp { from{transform:translate(-50%,100%)} to{transform:translate(-50%,0)} }
|
||||
@keyframes recSlideDown { from{transform:translate(-50%,0)} to{transform:translate(-50%,100%)} }
|
||||
</style>
|
||||
<script>
|
||||
let _recId = null;
|
||||
window.addEventListener('load', function() {
|
||||
{% if user_id %}
|
||||
setTimeout(async function() {
|
||||
try {
|
||||
const res = await fetch('/api/recommendation/{{ user_id }}');
|
||||
const data = await res.json();
|
||||
if (data.success && data.has_recommendation) {
|
||||
_recId = data.recommendation.id;
|
||||
document.getElementById('rec-message').textContent = data.recommendation.message;
|
||||
document.getElementById('rec-product').textContent = data.recommendation.product;
|
||||
document.getElementById('rec-sheet').style.display = 'block';
|
||||
document.getElementById('rec-backdrop').onclick = dismissRec;
|
||||
}
|
||||
} catch(e) {}
|
||||
}, 1500);
|
||||
{% endif %}
|
||||
});
|
||||
function dismissRec() {
|
||||
const c = document.getElementById('rec-content');
|
||||
const b = document.getElementById('rec-backdrop');
|
||||
c.style.animation = 'recSlideDown .3s ease forwards';
|
||||
b.style.opacity = '0';
|
||||
b.style.transition = 'opacity .3s';
|
||||
setTimeout(function(){ document.getElementById('rec-sheet').style.display='none'; }, 300);
|
||||
if (_recId) fetch('/api/recommendation/' + _recId + '/dismiss', {method:'POST'}).catch(function(){});
|
||||
}
|
||||
</script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/sw.js').catch(()=>{});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user