Add Ask Mento, customer mood, and Pipecat speech-to-text.
Ship assistant answers, contact moods, voice dictation, and the related CRM UI so these can be deployed to production. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
<script setup lang="ts">
|
||||
import type { PersonMood } from '@mento/shared';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
mood?: PersonMood | null;
|
||||
size?: number;
|
||||
}>(),
|
||||
{ mood: 'newcomer', size: 48 },
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
class="face"
|
||||
:class="mood || 'newcomer'"
|
||||
:style="{ width: `${size}px`, height: `${size}px` }"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<svg viewBox="0 0 64 64" fill="none">
|
||||
<circle class="skin" cx="32" cy="34" r="22" />
|
||||
<g class="shine">
|
||||
<ellipse cx="24" cy="26" rx="6" ry="3.2" />
|
||||
</g>
|
||||
|
||||
<g class="eyes">
|
||||
<g class="eye left">
|
||||
<ellipse class="open" cx="24" cy="33" rx="3.1" ry="3.6" />
|
||||
<path class="happy" d="M21 33c1.4-2.2 4.6-2.2 6 0" />
|
||||
<path class="sad" d="M21.4 34.6c1.2-2 4-2 5.2 0" />
|
||||
</g>
|
||||
<g class="eye right">
|
||||
<ellipse class="open" cx="40" cy="33" rx="3.1" ry="3.6" />
|
||||
<path class="happy" d="M37 33c1.4-2.2 4.6-2.2 6 0" />
|
||||
<path class="sad" d="M37.4 34.6c1.2-2 4-2 5.2 0" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<path class="mouth smile" d="M24 42c2.6 4.4 13.4 4.4 16 0" />
|
||||
<path class="mouth grin" d="M22 40.5c3.4 7 16.6 7 20 0" />
|
||||
<path class="mouth frown" d="M25 46c2.8-3.6 11.2-3.6 14 0" />
|
||||
|
||||
<g class="tears">
|
||||
<ellipse class="tear t1" cx="18" cy="40" rx="2.1" ry="3.2" />
|
||||
<ellipse class="tear t2" cx="46" cy="42" rx="2.1" ry="3.2" />
|
||||
</g>
|
||||
|
||||
<g class="crown">
|
||||
<path d="M16 18.5 22 26l10-9 10 9 6-7.5-2 12H18l-2-12Z" />
|
||||
<rect x="18" y="26" width="28" height="3.4" rx="1" />
|
||||
<circle class="gem" cx="32" cy="20" r="2.1" />
|
||||
<circle class="gem side" cx="22.5" cy="23" r="1.5" />
|
||||
<circle class="gem side" cx="41.5" cy="23" r="1.5" />
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.face {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
background: #fff7d6;
|
||||
box-shadow: inset 0 -3px 0 rgba(180, 120, 20, 0.08);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.skin {
|
||||
fill: #f5c542;
|
||||
}
|
||||
|
||||
.shine ellipse {
|
||||
fill: rgba(255, 255, 255, 0.35);
|
||||
}
|
||||
|
||||
.eye .open {
|
||||
fill: #3b2415;
|
||||
}
|
||||
|
||||
.eye .happy,
|
||||
.eye .sad,
|
||||
.mouth,
|
||||
.tears,
|
||||
.crown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.eye .happy,
|
||||
.eye .sad,
|
||||
.mouth {
|
||||
stroke: #3b2415;
|
||||
stroke-width: 2.4;
|
||||
stroke-linecap: round;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.face.newcomer .mouth.smile {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.face.happy {
|
||||
animation: bounce 1.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.face.happy .eye .open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.face.happy .eye .happy,
|
||||
.face.happy .mouth.grin {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.face.unhappy .eye .open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.face.unhappy .eye .sad,
|
||||
.face.unhappy .mouth.frown,
|
||||
.face.unhappy .tears {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tear {
|
||||
fill: #5bb7ff;
|
||||
}
|
||||
|
||||
.t1 {
|
||||
animation: drop 1.4s ease-in infinite;
|
||||
}
|
||||
|
||||
.t2 {
|
||||
animation: drop 1.4s ease-in 0.35s infinite;
|
||||
}
|
||||
|
||||
.face.special .mouth.smile,
|
||||
.face.special .crown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.face.special .crown {
|
||||
transform-origin: 32px 22px;
|
||||
animation: bob 1.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.crown path,
|
||||
.crown rect {
|
||||
fill: #f0b429;
|
||||
stroke: #c48414;
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.gem {
|
||||
fill: #ef4444;
|
||||
}
|
||||
|
||||
.gem.side {
|
||||
fill: #22c55e;
|
||||
}
|
||||
|
||||
.face.newcomer .eye .open,
|
||||
.face.special .eye .open {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
animation: blink 3.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%,
|
||||
42%,
|
||||
48%,
|
||||
100% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
45% {
|
||||
transform: scaleY(0.12);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes drop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bob {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0) rotate(-4deg);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-2px) rotate(4deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user