@@ -272,7 +491,7 @@
class="prof-card scroll-mt-20"
style="--c:#A78BFA;--c-dim:rgba(167,139,250,0.08);--c-border:rgba(167,139,250,0.2)"
>
-
-
05
+
07
@@ -623,6 +842,7 @@ const { setVariant } = _useLayout()
import Textarea from 'primevue/textarea'
import InputMask from 'primevue/inputmask'
import Checkbox from 'primevue/checkbox'
+import Select from 'primevue/select'
import { supabase } from '@/lib/supabase/client'
import { useLayout } from '@/layout/composables/layout'
@@ -661,10 +881,19 @@ const ui = reactive({
// Perfil
const form = reactive({
full_name: '',
+ nickname: '',
+ work_description: '',
+ work_description_other: '',
avatar_url: '',
bio: '',
phone: '',
+ site_url: '',
+ social_instagram: '',
+ social_youtube: '',
+ social_facebook: '',
+ social_x: '',
+
language: 'pt-BR',
timezone: 'America/Sao_Paulo',
@@ -673,13 +902,41 @@ const form = reactive({
notify_news: false
})
+const customSocials = ref([])
+
+function addCustomSocial () {
+ customSocials.value.push({ name: '', url: '' })
+ markDirty()
+}
+
+function removeCustomSocial (idx) {
+ customSocials.value.splice(idx, 1)
+ markDirty()
+}
+
+const workDescriptionOptions = [
+ { label: 'Psicólogo(a) Clínico(a)', value: 'psicologo_clinico' },
+ { label: 'Psicanalista', value: 'psicanalista' },
+ { label: 'Psiquiatra', value: 'psiquiatra' },
+ { label: 'Psicoterapeuta', value: 'psicoterapeuta' },
+ { label: 'Neuropsicólogo(a)', value: 'neuropsicologo' },
+ { label: 'Psicólogo(a) Organizacional', value: 'psicologo_organizacional' },
+ { label: 'Psicólogo(a) Escolar / Educacional', value: 'psicologo_escolar' },
+ { label: 'Psicólogo(a) Hospitalar', value: 'psicologo_hospitalar' },
+ { label: 'Psicólogo(a) Jurídico(a)', value: 'psicologo_juridico' },
+ { label: 'Coach / Mentor(a)', value: 'coach_mentor' },
+ { label: 'Terapeuta Holístico(a)', value: 'terapeuta_holistico' },
+ { label: 'Outro', value: 'outro' },
+]
+
const sections = [
- { id: 'conta', label: 'Conta', icon: 'pi pi-user' },
- { id: 'avatar', label: 'Avatar', icon: 'pi pi-image' },
- { id: 'layout', label: 'Aparência', icon: 'pi pi-palette' },
- { id: 'preferencias', label: 'Preferências', icon: 'pi pi-sliders-h' },
- { id: 'seguranca', label: 'Segurança', icon: 'pi pi-shield' },
- { id: 'layout-variant', label: 'Layout', icon: 'pi pi-th-large' }
+ { id: 'conta', label: 'Conta', icon: 'pi pi-user' },
+ { id: 'redes-sociais', label: 'Sites e Redes', icon: 'pi pi-share-alt' },
+ { id: 'avatar', label: 'Avatar', icon: 'pi pi-image' },
+ { id: 'layout', label: 'Aparência', icon: 'pi pi-palette' },
+ { id: 'preferencias', label: 'Preferências', icon: 'pi pi-sliders-h' },
+ { id: 'layout-variant', label: 'Layout', icon: 'pi pi-th-large' },
+ { id: 'seguranca', label: 'Segurança', icon: 'pi pi-shield' },
]
const activeSection = ref('conta')
@@ -968,13 +1225,15 @@ async function loadUserSettings (uid) {
if (settings.surface_color && !safeEq(settings.surface_color, layoutConfig.surface)) layoutConfig.surface = settings.surface_color
if (settings.menu_mode && !safeEq(settings.menu_mode, layoutConfig.menuMode)) {
layoutConfig.menuMode = settings.menu_mode
- try { changeMenuMode?.(settings.menu_mode) } catch {
- try { changeMenuMode?.({ value: settings.menu_mode }) } catch {}
- }
+ // Não chama changeMenuMode() — ela reseta staticMenuInactive e outros estados,
+ // fazendo a sidebar desaparecer ao entrar na página.
}
- // layout variant
- if (settings.layout_variant === 'rail' || settings.layout_variant === 'classic') {
+ // layout variant — só aplica se mudou, para não resetar o estado do layout
+ if (
+ (settings.layout_variant === 'rail' || settings.layout_variant === 'classic') &&
+ settings.layout_variant !== layoutConfig.variant
+ ) {
setVariant(settings.layout_variant)
}
@@ -1026,7 +1285,7 @@ async function loadProfile () {
const { data: prof, error: pErr } = await supabase
.from('profiles')
- .select('full_name, avatar_url, phone, bio, language, timezone, notify_system_email, notify_reminders, notify_news')
+ .select('full_name, avatar_url, phone, bio, nickname, work_description, work_description_other, site_url, social_instagram, social_youtube, social_facebook, social_x, social_custom, language, timezone, notify_system_email, notify_reminders, notify_news')
.eq('id', user.id)
.maybeSingle()
@@ -1035,6 +1294,18 @@ async function loadProfile () {
form.avatar_url = prof.avatar_url ?? form.avatar_url
form.phone = prof.phone ?? ''
form.bio = prof.bio ?? ''
+ form.nickname = prof.nickname ?? ''
+ form.work_description = prof.work_description ?? ''
+ form.work_description_other = prof.work_description_other ?? ''
+ form.site_url = prof.site_url ?? ''
+ form.social_instagram = prof.social_instagram ?? ''
+ form.social_youtube = prof.social_youtube ?? ''
+ form.social_facebook = prof.social_facebook ?? ''
+ form.social_x = prof.social_x ?? ''
+
+ if (Array.isArray(prof.social_custom)) {
+ customSocials.value = prof.social_custom
+ }
form.language = prof.language ?? form.language
form.timezone = prof.timezone ?? form.timezone
@@ -1087,6 +1358,15 @@ async function saveAll () {
avatar_url: metaPayload.avatar_url,
phone: String(form.phone || '').trim() || null,
bio: String(form.bio || '').trim() || null,
+ nickname: String(form.nickname || '').trim() || null,
+ work_description: String(form.work_description || '').trim() || null,
+ work_description_other: form.work_description === 'outro' ? (String(form.work_description_other || '').trim() || null) : null,
+ site_url: String(form.site_url || '').trim() || null,
+ social_instagram: String(form.social_instagram || '').trim() || null,
+ social_youtube: String(form.social_youtube || '').trim() || null,
+ social_facebook: String(form.social_facebook || '').trim() || null,
+ social_x: String(form.social_x || '').trim() || null,
+ social_custom: customSocials.value.filter(s => s.name || s.url),
language: form.language || 'pt-BR',
timezone: form.timezone || 'America/Sao_Paulo',
@@ -1100,7 +1380,7 @@ async function saveAll () {
.from('profiles')
.update(profilePayload)
.eq('id', userId.value)
- .select('id, role, full_name, avatar_url, phone, bio, language, timezone, notify_system_email, notify_reminders, notify_news, updated_at')
+ .select('id, role, full_name, avatar_url, phone, bio, nickname, work_description, work_description_other, site_url, social_instagram, social_youtube, social_facebook, social_x, social_custom, language, timezone, notify_system_email, notify_reminders, notify_news, updated_at')
.single()
if (pErr2) {
@@ -1644,4 +1924,39 @@ onBeforeUnmount(() => {
from { opacity: 0; transform: translateY(14px); }
to { opacity: 1; transform: translateY(0); }
}
+
+/* ─── Social addons ─────────────────────────────────────── */
+.social-addon {
+ display: flex; align-items: center; justify-content: center;
+ width: 2.75rem; flex-shrink: 0;
+ font-size: 0.95rem;
+}
+.social-addon--site { color: var(--text-color-secondary); }
+.social-addon--instagram { color: #E1306C; }
+.social-addon--youtube { color: #FF0000; }
+.social-addon--facebook { color: #1877F2; }
+.social-addon--x { color: var(--text-color); }
+
+/* FloatLabel com inputgroup: label offset pelo addon */
+.social-float-label {
+ left: 2.85rem !important;
+}
+
+/* Fix FloatLabel wrapping inputgroup */
+.p-floatlabel:has(.p-inputgroup) { display: block; }
+.p-floatlabel .p-inputgroup { width: 100%; }
+.p-floatlabel .p-inputgroup .p-inputtext {
+ border-radius: 0 var(--p-inputtext-border-radius, 8px) var(--p-inputtext-border-radius, 8px) 0 !important;
+}
+
+/* ─── Transition "outro" ────────────────────────────────── */
+.prof-slide-enter-active,
+.prof-slide-leave-active {
+ transition: opacity 0.2s ease, max-height 0.25s ease, margin 0.2s ease;
+ max-height: 6rem; overflow: hidden;
+}
+.prof-slide-enter-from,
+.prof-slide-leave-to {
+ opacity: 0; max-height: 0; margin: 0;
+}