Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring Platform content
Preparing Ring Platform content
Preparing Ring Platform content
Use Founder / Developer tabs in the docs sidebar to filter this page. Public /{username} surfaces are separate — see Public Profile Pages. Entity catalog powering Organization is documented under Entities.
Signed-in members manage account vitals on /profile. The Professional tab ships three composed widgets under components/profile/ (app UI — not MDX ring-widgets):
| Widget | Job |
|---|---|
| OrganizationEntitySelect | Pick organization from all Entities via Davinci-droplist |
| PositionTagCloud / SkillsTagCloud | Multi-tag FsModal clouds (shared ProfileTagCloud) |
| CurriculumVitaeWidget | Markdown CV editor + profile:cv file upload |
Human catalog (with Davinci-droplist call sites): components/docs/WIDGETS-README.md → App UI profile widgets. Machine index: AI-CONTEXT/concepts/ring-docs.nodus.json → ring_widgets.index.sections.app_ui_profile.
Professional fields turn a bare account into a hireable / partnerable face: which organization the member represents, which roles and skills they claim, and a CV they can edit on a phone without fighting chrome padding.
Typical scenarios:
/profile → Professional → taps Organization → searchable Entity list (FsModal) → selection saves immediately.Next-step: public /{username} trust face after Professional fields are filled.
Depends-on: OrganizationEntitySelect lists Entities from GET /api/entities.
Same-workflow: /profile vitals and Auth.js session.update after updateProfile.
See-also: publications use useAutoSave against /api/publications; CV drafts use useLocalStorage instead.
Use Founder / Developer tabs in the docs sidebar to filter this page. Public /{username} surfaces are separate — see Public Profile Pages. Entity catalog powering Organization is documented under Entities.
Signed-in members manage account vitals on /profile. The Professional tab ships three composed widgets under components/profile/ (app UI — not MDX ring-widgets):
| Widget | Job |
|---|---|
| OrganizationEntitySelect | Pick organization from all Entities via Davinci-droplist |
| PositionTagCloud / SkillsTagCloud | Multi-tag FsModal clouds (shared ProfileTagCloud) |
| CurriculumVitaeWidget | Markdown CV editor + profile:cv file upload |
Human catalog (with Davinci-droplist call sites): components/docs/WIDGETS-README.md → App UI profile widgets. Machine index: AI-CONTEXT/concepts/ring-docs.nodus.json → ring_widgets.index.sections.app_ui_profile.
Professional fields turn a bare account into a hireable / partnerable face: which organization the member represents, which roles and skills they claim, and a CV they can edit on a phone without fighting chrome padding.
Typical scenarios:
/profile → Professional → taps Organization → searchable Entity list (FsModal) → selection saves immediately.Next-step: public /{username} trust face after Professional fields are filled.
Depends-on: OrganizationEntitySelect lists Entities from GET /api/entities.
Same-workflow: /profile vitals and Auth.js session.update after updateProfile.
See-also: publications use useAutoSave against /api/publications; CV drafts use useLocalStorage instead.
Use Founder / Developer tabs in the docs sidebar to filter this page. Public /{username} surfaces are separate — see Public Profile Pages. Entity catalog powering Organization is documented under Entities.
Signed-in members manage account vitals on /profile. The Professional tab ships three composed widgets under components/profile/ (app UI — not MDX ring-widgets):
| Widget | Job |
|---|---|
| OrganizationEntitySelect | Pick organization from all Entities via Davinci-droplist |
| PositionTagCloud / SkillsTagCloud | Multi-tag FsModal clouds (shared ProfileTagCloud) |
| CurriculumVitaeWidget | Markdown CV editor + profile:cv file upload |
Human catalog (with Davinci-droplist call sites): components/docs/WIDGETS-README.md → App UI profile widgets. Machine index: AI-CONTEXT/concepts/ring-docs.nodus.json → ring_widgets.index.sections.app_ui_profile.
Professional fields turn a bare account into a hireable / partnerable face: which organization the member represents, which roles and skills they claim, and a CV they can edit on a phone without fighting chrome padding.
Typical scenarios:
/profile → Professional → taps Organization → searchable Entity list (FsModal) → selection saves immediately.Next-step: public /{username} trust face after Professional fields are filled.
Depends-on: OrganizationEntitySelect lists Entities from GET /api/entities.
Same-workflow: /profile vitals and Auth.js session.update after updateProfile.
See-also: publications use useAutoSave against /api/publications; CV drafts use useLocalStorage instead.
@handle lives on Messengers tab (above Telegram) — not in the Professional hero.
updateProfilecurriculumVitaeorganizationpositionskills| Upload | POST /api/uploads purpose profile:cv (lib/uploads/upload-types.ts) |
| Storage shape | users.data.curriculumVitae (CurriculumVitae in features/auth/types.ts) |
| Drafts | useLocalStorage key profile_cv_draft_{userId} + useDebounce (same hydration-safe pattern as chat composer) |
| Shell | FsModal — mobile hideTitleOnMobile, closeClassName="max-sm:hidden", footer Close + Save & Exit |
OrganizationEntitySelect is a migrated Davinci-droplist call site (theme enhancer §7 / DL11), alongside CountrySelect, TimezoneSelect, ProductRepSelect, VendorEntitySelect. ProfileTagCloud reuses DavinciDroplistItem + QuickSearchFilter inside FsModal for multi-tag confirm (not single-select close-on-tap).
Desktop keeps Cancel + Save labels and the default top-right .modal-close-button.
Import OrganizationEntitySelect into the Professional tab; pass current organization string and onSaved to refresh local profile state after updateProfile.
Use PositionTagCloud / SkillsTagCloud wrappers (or ProfileTagCloud directly with a field + knownTags). Selected chips render both outside and inside the FsModal.
Mount CurriculumVitaeWidget with value={user.curriculumVitae}. Ensure upload purpose profile:cv is allowed in upload-core and that updateProfile parses curriculumVitae JSON into users.data.
Deep-dive: WIDGETS-README App UI profile widgets + ring-docs.nodus app_ui_profile section.
@handle lives on Messengers tab (above Telegram) — not in the Professional hero.
updateProfilecurriculumVitaeorganizationpositionskills| Upload | POST /api/uploads purpose profile:cv (lib/uploads/upload-types.ts) |
| Storage shape | users.data.curriculumVitae (CurriculumVitae in features/auth/types.ts) |
| Drafts | useLocalStorage key profile_cv_draft_{userId} + useDebounce (same hydration-safe pattern as chat composer) |
| Shell | FsModal — mobile hideTitleOnMobile, closeClassName="max-sm:hidden", footer Close + Save & Exit |
OrganizationEntitySelect is a migrated Davinci-droplist call site (theme enhancer §7 / DL11), alongside CountrySelect, TimezoneSelect, ProductRepSelect, VendorEntitySelect. ProfileTagCloud reuses DavinciDroplistItem + QuickSearchFilter inside FsModal for multi-tag confirm (not single-select close-on-tap).
Desktop keeps Cancel + Save labels and the default top-right .modal-close-button.
Import OrganizationEntitySelect into the Professional tab; pass current organization string and onSaved to refresh local profile state after updateProfile.
Use PositionTagCloud / SkillsTagCloud wrappers (or ProfileTagCloud directly with a field + knownTags). Selected chips render both outside and inside the FsModal.
Mount CurriculumVitaeWidget with value={user.curriculumVitae}. Ensure upload purpose profile:cv is allowed in upload-core and that updateProfile parses curriculumVitae JSON into users.data.
Deep-dive: WIDGETS-README App UI profile widgets + ring-docs.nodus app_ui_profile section.
@handle lives on Messengers tab (above Telegram) — not in the Professional hero.
updateProfilecurriculumVitaeorganizationpositionskills| Upload | POST /api/uploads purpose profile:cv (lib/uploads/upload-types.ts) |
| Storage shape | users.data.curriculumVitae (CurriculumVitae in features/auth/types.ts) |
| Drafts | useLocalStorage key profile_cv_draft_{userId} + useDebounce (same hydration-safe pattern as chat composer) |
| Shell | FsModal — mobile hideTitleOnMobile, closeClassName="max-sm:hidden", footer Close + Save & Exit |
OrganizationEntitySelect is a migrated Davinci-droplist call site (theme enhancer §7 / DL11), alongside CountrySelect, TimezoneSelect, ProductRepSelect, VendorEntitySelect. ProfileTagCloud reuses DavinciDroplistItem + QuickSearchFilter inside FsModal for multi-tag confirm (not single-select close-on-tap).
Desktop keeps Cancel + Save labels and the default top-right .modal-close-button.
Import OrganizationEntitySelect into the Professional tab; pass current organization string and onSaved to refresh local profile state after updateProfile.
Use PositionTagCloud / SkillsTagCloud wrappers (or ProfileTagCloud directly with a field + knownTags). Selected chips render both outside and inside the FsModal.
Mount CurriculumVitaeWidget with value={user.curriculumVitae}. Ensure upload purpose profile:cv is allowed in upload-core and that updateProfile parses curriculumVitae JSON into users.data.
Deep-dive: WIDGETS-README App UI profile widgets + ring-docs.nodus app_ui_profile section.
// Draft key SSOT (curriculum-vitae-widget.tsx)
const draftKey = userId ? `profile_cv_draft_${userId}` : 'profile_cv_draft'
const [storedDraft, setStoredDraft] = useLocalStorage<string>(draftKey, '')
max-sm: full viewport, body padding 0, header hidden
footer: [Close] ············ [Save & Exit]
draft: useLocalStorage autosave while open
action: Save & Exit → updateProfile → clear draft → close
// Draft key SSOT (curriculum-vitae-widget.tsx)
const draftKey = userId ? `profile_cv_draft_${userId}` : 'profile_cv_draft'
const [storedDraft, setStoredDraft] = useLocalStorage<string>(draftKey, '')
max-sm: full viewport, body padding 0, header hidden
footer: [Close] ············ [Save & Exit]
draft: useLocalStorage autosave while open
action: Save & Exit → updateProfile → clear draft → close
// Draft key SSOT (curriculum-vitae-widget.tsx)
const draftKey = userId ? `profile_cv_draft_${userId}` : 'profile_cv_draft'
const [storedDraft, setStoredDraft] = useLocalStorage<string>(draftKey, '')
max-sm: full viewport, body padding 0, header hidden
footer: [Close] ············ [Save & Exit]
draft: useLocalStorage autosave while open
action: Save & Exit → updateProfile → clear draft → close