2024-10-22 01:12:42 +00:00
|
|
|
<template>
|
|
|
|
<div class="editor">
|
|
|
|
<p
|
|
|
|
v-if="submitted"
|
|
|
|
class="submitted"
|
|
|
|
>
|
|
|
|
<template v-if="apply">Your revision has been submitted. Thank you for your contribution!</template>
|
|
|
|
<template v-else>Your revision has been submitted for review. Thank you for your contribution!</template>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
<a
|
|
|
|
:href="`/actor/${actor.id}/${actor.slug}`"
|
|
|
|
class="link"
|
|
|
|
>Return to actor</a>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li>
|
|
|
|
<a
|
|
|
|
:href="`/actor/edit/${actor.id}`"
|
|
|
|
class="link"
|
|
|
|
>Make another edit</a>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li>
|
|
|
|
<a
|
2024-10-22 23:28:54 +00:00
|
|
|
:href="`/actor/revs/${actor.id}/${actor.slug}`"
|
2024-10-22 01:12:42 +00:00
|
|
|
class="link"
|
|
|
|
>Go to actor revisions</a>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li>
|
|
|
|
<a
|
|
|
|
:href="`/user/${user.username}/revisions`"
|
|
|
|
class="link"
|
|
|
|
>Go to user revisions</a>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li v-if="user.role !== 'user'">
|
|
|
|
<a
|
|
|
|
href="/admin/revisions/actors"
|
|
|
|
class="link"
|
|
|
|
>Go to revisions admin</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<form
|
|
|
|
v-else
|
|
|
|
@submit.prevent
|
|
|
|
>
|
|
|
|
<div class="editor-header">
|
|
|
|
<h2 class="heading ellipsis">Edit actor #{{ actor.id }} - {{ actor.name }}</h2>
|
|
|
|
|
|
|
|
<a
|
|
|
|
:href="`/actor/${actor.id}/${actor.slug}`"
|
|
|
|
target="_blank"
|
|
|
|
class="link noshrink"
|
|
|
|
>Go to actor</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<ul class="nolist">
|
|
|
|
<li
|
|
|
|
v-for="item in fields"
|
|
|
|
:key="`item-${item.key}`"
|
|
|
|
class="row"
|
|
|
|
>
|
|
|
|
<div class="item-header">
|
|
|
|
<div class="key">{{ item.label || item.key }}</div>
|
|
|
|
|
|
|
|
<div class="item-actions">
|
|
|
|
<Icon
|
|
|
|
v-if="!item.forced"
|
|
|
|
icon="pencil5"
|
|
|
|
:class="{ active: editing.has(item.key) }"
|
|
|
|
@click="toggleField(item)"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
class="value"
|
|
|
|
:class="{ disabled: !editing.has(item.key) }"
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
v-if="item.type === 'string'"
|
|
|
|
v-model="edits[item.key]"
|
|
|
|
class="string input"
|
2024-10-22 23:28:54 +00:00
|
|
|
:list="item.suggestions && `suggestions-${item.key}`"
|
2024-10-22 01:12:42 +00:00
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
|
2024-10-22 23:28:54 +00:00
|
|
|
<datalist
|
|
|
|
v-if="item.suggestions"
|
|
|
|
:id="`suggestions-${item.key}`"
|
|
|
|
>
|
|
|
|
<option
|
|
|
|
v-for="(suggestion, index) in item.suggestions"
|
|
|
|
:key="`suggestion-${item.key}-${index}`"
|
|
|
|
>{{ suggestion }}</option>
|
|
|
|
</datalist>
|
|
|
|
|
2024-10-22 01:12:42 +00:00
|
|
|
<textarea
|
|
|
|
v-if="item.type === 'text'"
|
|
|
|
v-model="edits[item.key]"
|
|
|
|
:placeholder="item.placeholder"
|
|
|
|
rows="3"
|
|
|
|
class="text input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<template v-if="item.type === 'number'">
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key]"
|
|
|
|
type="number"
|
|
|
|
:max="item.max"
|
|
|
|
:min="item.min"
|
|
|
|
class="number input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>{{ item.unit }}
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-if="item.type === 'date'"
|
|
|
|
v-model="edits[item.key]"
|
|
|
|
type="date"
|
|
|
|
class="date input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-if="item.type === 'select'"
|
|
|
|
v-model="edits[item.key]"
|
|
|
|
class="select input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option
|
|
|
|
v-for="option in item.options"
|
|
|
|
:key="`${item.key}-option-${option}`"
|
|
|
|
:value="typeof option?.value === 'undefined' ? option : option.value"
|
|
|
|
>{{ option?.label || option || 'unknown' }}</option>
|
|
|
|
</select>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'place'"
|
|
|
|
class="place"
|
|
|
|
>
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Country</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].country"
|
|
|
|
class="select input"
|
|
|
|
placeholder="Country"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option
|
|
|
|
:key="`${item.key}-country-unknown`"
|
|
|
|
:value="null"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<option
|
|
|
|
v-for="country in sortedCountries"
|
|
|
|
:key="`${item.key}-country-${country.alpha2}`"
|
|
|
|
:value="country.alpha2"
|
|
|
|
>{{ country.alias || country.name }}</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">State</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].state"
|
|
|
|
class="string input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">City</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].city"
|
|
|
|
class="string input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'figure'"
|
|
|
|
class="figure"
|
|
|
|
>
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Units</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="figureSystem"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option value="us">USA</option>
|
|
|
|
<option value="eu">Europe/Asia</option>
|
|
|
|
<option value="jp">Japan</option>
|
|
|
|
<option value="aus">Australia</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<span class="figure-bust">
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Bust</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].bust"
|
|
|
|
type="number"
|
|
|
|
class="input"
|
|
|
|
placeholder="Bust"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Cup</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].cup"
|
|
|
|
class="select input"
|
|
|
|
placeholder="Cup"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option
|
|
|
|
:key="`${item.key}-cup-unknown`"
|
|
|
|
:value="null"
|
|
|
|
>Unknown</option>
|
|
|
|
|
|
|
|
<option
|
|
|
|
v-for="cup in cupSizes"
|
|
|
|
:key="`${item.key}-cup-${cup}`"
|
|
|
|
:value="cup"
|
|
|
|
>{{ cup }}</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Waist</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].waist"
|
|
|
|
type="number"
|
|
|
|
class="input"
|
|
|
|
placeholder="Waist"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Hip</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].hip"
|
|
|
|
type="number"
|
|
|
|
class="input"
|
|
|
|
placeholder="Hip"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'augmentation'"
|
|
|
|
class="figure augmentation"
|
|
|
|
>
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Natural boobs</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].naturalBoobs"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option :value="true">Yes</option>
|
|
|
|
<option :value="false">No</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalBoobs === false"
|
|
|
|
class="value-section"
|
|
|
|
>
|
|
|
|
<span class="value-label">Implant CC</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].boobsVolume"
|
|
|
|
type="number"
|
|
|
|
class="volume input"
|
|
|
|
placeholder="CC"
|
|
|
|
min="50"
|
|
|
|
max="10000"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalBoobs === false"
|
|
|
|
class="value-section"
|
|
|
|
>
|
|
|
|
<span class="value-label">Implant type</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].boobsImplant"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option value="saline">Saline</option>
|
|
|
|
<option value="silicone">Silicone</option>
|
|
|
|
<option value="gummy">Gummy</option>
|
|
|
|
<option value="fat">Fat transfer</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalBoobs === false"
|
|
|
|
class="value-section"
|
|
|
|
>
|
|
|
|
<span class="value-label">Implant placement</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].boobsPlacement"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option value="over">Over muscle</option>
|
|
|
|
<option value="under">Under muscle</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalBoobs === false"
|
|
|
|
class="value-section value-divide"
|
|
|
|
>
|
|
|
|
<span class="value-label">Surgeon</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].boobsSurgeon"
|
|
|
|
class="volume input"
|
|
|
|
placeholder="Surgeon"
|
|
|
|
list="surgeons"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
|
|
|
|
<datalist id="surgeons">
|
|
|
|
<option value="Dr. Revis" />
|
|
|
|
<option value="Dr. Dre" />
|
|
|
|
</datalist>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Natural butt</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].naturalButt"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option :value="true">Yes</option>
|
|
|
|
<option :value="false">No</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalButt === false"
|
|
|
|
class="value-section"
|
|
|
|
>
|
|
|
|
<span class="value-label">Implant CC</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].buttVolume"
|
|
|
|
type="number"
|
|
|
|
class="volume input"
|
|
|
|
placeholder="CC"
|
|
|
|
min="50"
|
|
|
|
max="10000"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="edits[item.key].naturalButt === false"
|
|
|
|
class="value-section"
|
|
|
|
>
|
|
|
|
<span class="value-label">Implant type</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].buttImplant"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option value="bbl">BBL (fat transfer)</option>
|
|
|
|
<option value="lift">Direct lift</option>
|
|
|
|
<option value="filler">Filler (Sculptra)</option>
|
|
|
|
<option value="mms">MMS (CoolTone)</option>
|
|
|
|
<option value="lipo">Lipo without BBL</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'penis'"
|
|
|
|
class="figure penis"
|
|
|
|
>
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Units</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="penisSystem"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option value="imperial">Imperial</option>
|
|
|
|
<option value="metric">Metric</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Penis length</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].penisLength"
|
|
|
|
type="number"
|
|
|
|
class="volume input"
|
|
|
|
min="1"
|
|
|
|
max="20"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Penis girth</span>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].penisGirth"
|
|
|
|
type="number"
|
|
|
|
class="volume input"
|
|
|
|
min="1"
|
|
|
|
max="20"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="value-section">
|
|
|
|
<span class="value-label">Circumcised</span>
|
|
|
|
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].isCircumcised"
|
|
|
|
class="input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option :value="true">Yes</option>
|
|
|
|
<option :value="false">No</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'has'"
|
|
|
|
class="has"
|
|
|
|
>
|
|
|
|
<select
|
|
|
|
v-model="edits[item.key].has"
|
|
|
|
class="select input"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
<option :value="null">Unknown</option>
|
|
|
|
<option :value="true">Yes</option>
|
|
|
|
<option :value="false">No</option>
|
|
|
|
</select>
|
|
|
|
|
|
|
|
<input
|
|
|
|
v-model="edits[item.key].description"
|
|
|
|
class="description input"
|
|
|
|
placeholder="Description"
|
|
|
|
:disabled="!editing.has(item.key)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="item.type === 'avatar'"
|
|
|
|
class="avatars"
|
|
|
|
:class="{ disabled: !editing.has(item.key) }"
|
|
|
|
>
|
2024-10-22 23:28:54 +00:00
|
|
|
<Avatar
|
2024-10-22 01:12:42 +00:00
|
|
|
v-for="avatar in item.options"
|
|
|
|
:key="`avatar-${avatar.id}`"
|
2024-10-22 23:28:54 +00:00
|
|
|
:avatar="avatar"
|
2024-10-22 01:12:42 +00:00
|
|
|
:class="{ selected: edits[item.key] === avatar.id }"
|
|
|
|
@click="setAvatar(avatar.id)"
|
2024-10-22 23:28:54 +00:00
|
|
|
/>
|
2024-10-22 01:12:42 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<div class="editor-footer">
|
|
|
|
<div class="comment">
|
|
|
|
<textarea
|
|
|
|
v-model="comment"
|
|
|
|
rows="3"
|
|
|
|
placeholder="Please provide verifiable information and sources supporting your edits."
|
|
|
|
class="text input noshrink"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="editor-actions">
|
|
|
|
<Checkbox
|
|
|
|
v-if="user.role !== 'user'"
|
|
|
|
label="Approve and apply immediately"
|
|
|
|
:checked="apply"
|
|
|
|
:disabled="editing.size === 0"
|
|
|
|
@change="(checked) => apply = checked"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<!-- we don't want the return key to submit the form -->
|
|
|
|
<button
|
|
|
|
class="button button-primary"
|
|
|
|
type="button"
|
|
|
|
:disabled="editing.size === 0"
|
|
|
|
@click="submit"
|
|
|
|
>
|
|
|
|
<template v-if="apply">Submit</template>
|
|
|
|
<template v-else>Submit for review</template>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
import { ref, computed, inject } from 'vue';
|
|
|
|
import { format } from 'date-fns';
|
|
|
|
|
2024-10-22 23:28:54 +00:00
|
|
|
import Avatar from '#/components/edit/avatar.vue';
|
2024-10-22 01:12:42 +00:00
|
|
|
import Checkbox from '#/components/form/checkbox.vue';
|
|
|
|
|
|
|
|
import {
|
|
|
|
// get,
|
|
|
|
post,
|
|
|
|
} from '#/src/api.js';
|
|
|
|
|
|
|
|
const pageContext = inject('pageContext');
|
|
|
|
|
|
|
|
const user = pageContext.user;
|
|
|
|
const countries = pageContext.pageProps.countries;
|
|
|
|
const actor = ref(pageContext.pageProps.actor);
|
|
|
|
|
|
|
|
const topCountries = [
|
|
|
|
'AU',
|
|
|
|
'BR',
|
|
|
|
'CZ',
|
|
|
|
'DE',
|
|
|
|
'JP',
|
|
|
|
'RU',
|
|
|
|
'GB',
|
|
|
|
'US',
|
|
|
|
];
|
|
|
|
|
|
|
|
const sortedCountries = countries.toSorted((countryA, countryB) => topCountries.indexOf(countryB.alpha2) - topCountries.indexOf(countryA.alpha2));
|
|
|
|
|
|
|
|
const cupSizes = [
|
|
|
|
'A', 'AA',
|
|
|
|
'B',
|
|
|
|
'C',
|
|
|
|
'D', 'DD', 'DDD',
|
|
|
|
'E',
|
|
|
|
'F', 'FF',
|
|
|
|
'G', 'GG',
|
|
|
|
'H', 'HH',
|
|
|
|
'J', 'JJ',
|
|
|
|
'K', 'KK',
|
|
|
|
'L',
|
|
|
|
'M',
|
|
|
|
'N',
|
|
|
|
'O',
|
|
|
|
'P',
|
|
|
|
];
|
|
|
|
|
|
|
|
const fields = computed(() => [
|
|
|
|
{
|
|
|
|
key: 'avatar',
|
|
|
|
type: 'avatar',
|
|
|
|
value: actor.value.avatar.id,
|
|
|
|
options: Object.values(Object.fromEntries(actor.value.profiles.filter((profile) => !!profile.avatar).map((profile) => [profile.avatar.id, profile.avatar]))),
|
|
|
|
},
|
|
|
|
...(user.role === 'admin'
|
|
|
|
? [{
|
|
|
|
key: 'name',
|
|
|
|
type: 'string',
|
|
|
|
value: actor.value.name,
|
|
|
|
}]
|
|
|
|
: []),
|
|
|
|
{
|
|
|
|
key: 'gender',
|
|
|
|
type: 'select',
|
|
|
|
value: actor.value.gender,
|
|
|
|
options: ['female', 'male', 'transsexual', 'other', null],
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'dateOfBirth',
|
|
|
|
label: 'date of birth',
|
|
|
|
type: 'date',
|
|
|
|
value: actor.value.dateOfBirth
|
|
|
|
? format(actor.value.dateOfBirth, 'yyyy-MM-dd')
|
|
|
|
: null,
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'origin',
|
|
|
|
type: 'place',
|
|
|
|
value: {
|
|
|
|
...actor.value.origin,
|
|
|
|
country: actor.value.origin?.country?.alpha2 || null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'residence',
|
|
|
|
type: 'place',
|
|
|
|
value: {
|
|
|
|
...actor.value.residence,
|
|
|
|
country: actor.value.residence?.country?.alpha2 || null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'height',
|
|
|
|
type: 'number',
|
2024-10-22 23:28:54 +00:00
|
|
|
value: actor.value.height?.metric,
|
2024-10-22 01:12:42 +00:00
|
|
|
unit: 'cm',
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'weight',
|
|
|
|
type: 'number',
|
2024-10-22 23:28:54 +00:00
|
|
|
value: actor.value.weight?.metric,
|
2024-10-22 01:12:42 +00:00
|
|
|
unit: 'kg',
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'figure',
|
|
|
|
type: 'figure',
|
|
|
|
value: {
|
|
|
|
bust: actor.value.bust,
|
|
|
|
cup: actor.value.cup,
|
|
|
|
waist: actor.value.waist,
|
|
|
|
hip: actor.value.hip,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'augmentation',
|
|
|
|
type: 'augmentation',
|
|
|
|
value: {
|
|
|
|
naturalBoobs: actor.value.naturalBoobs,
|
|
|
|
boobsVolume: actor.value.boobsVolume,
|
|
|
|
boobsImplant: actor.value.boobsImplant,
|
|
|
|
boobsPlacement: actor.value.boobsPlacement,
|
|
|
|
boobsSurgeon: actor.value.boobsSurgeon,
|
|
|
|
naturalButt: actor.value.naturalButt,
|
|
|
|
buttVolume: actor.value.buttVolume,
|
|
|
|
buttImplant: actor.value.buttImplant,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'hairColor',
|
|
|
|
label: 'hair color',
|
|
|
|
type: 'select',
|
|
|
|
value: actor.value.hairColor,
|
|
|
|
options: [
|
|
|
|
null,
|
|
|
|
'black',
|
|
|
|
'blonde',
|
|
|
|
'brown',
|
|
|
|
'red',
|
|
|
|
'gray',
|
|
|
|
'blue',
|
|
|
|
'green',
|
|
|
|
'pink',
|
|
|
|
'purple',
|
|
|
|
],
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'eyes',
|
|
|
|
label: 'eye color',
|
|
|
|
type: 'select',
|
|
|
|
value: actor.value.eyes,
|
|
|
|
options: [
|
|
|
|
null,
|
|
|
|
'blue',
|
|
|
|
'brown',
|
|
|
|
'gray',
|
|
|
|
'green',
|
|
|
|
'hazel',
|
|
|
|
],
|
|
|
|
inline: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'tattoos',
|
|
|
|
type: 'has',
|
|
|
|
value: {
|
|
|
|
has: actor.value.hasTattoos,
|
|
|
|
description: actor.value.tattoos,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'piercings',
|
|
|
|
type: 'has',
|
|
|
|
value: {
|
|
|
|
has: actor.value.hasPiercings,
|
|
|
|
description: actor.value.piercings,
|
|
|
|
},
|
|
|
|
},
|
2024-10-22 23:28:54 +00:00
|
|
|
{
|
|
|
|
key: 'agency',
|
|
|
|
type: 'string',
|
|
|
|
value: actor.value.agency,
|
|
|
|
suggestions: [
|
|
|
|
'101 Modeling',
|
|
|
|
'Adult Talent Managers (ATMLA)',
|
|
|
|
'The Bakery Talent',
|
|
|
|
'Coxxx Models',
|
|
|
|
'East Coast Talent (ECT)',
|
|
|
|
'Hussie Models',
|
|
|
|
'Invision Models',
|
|
|
|
'OC Modeling',
|
|
|
|
'Spiegler Girls',
|
|
|
|
],
|
|
|
|
},
|
2024-10-22 01:12:42 +00:00
|
|
|
{
|
|
|
|
key: 'penis',
|
|
|
|
type: 'penis',
|
|
|
|
value: {
|
|
|
|
penisLength: actor.value.penisLength,
|
|
|
|
penisGirth: actor.value.penisGirth,
|
|
|
|
isCircumcised: actor.value.isCircumcised,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'dateOfDeath',
|
|
|
|
label: 'date of death',
|
|
|
|
type: 'date',
|
|
|
|
value: actor.value.dateOfDeath
|
|
|
|
? format(actor.value.dateOfDeath, 'yyyy-MM-dd')
|
|
|
|
: null,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const editing = ref(new Set());
|
|
|
|
const edits = ref(Object.fromEntries(fields.value.map((field) => [field.key, field.value])));
|
|
|
|
const comment = ref(null);
|
|
|
|
const apply = ref(user.role !== 'user');
|
|
|
|
const submitted = ref(false);
|
|
|
|
|
|
|
|
const figureSystem = ref('us');
|
|
|
|
const penisSystem = ref('imperial');
|
|
|
|
|
|
|
|
function toggleField(item) {
|
|
|
|
if (editing.value.has(item.key)) {
|
|
|
|
editing.value.delete(item.key);
|
|
|
|
// delete edits.value[item.key];
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
editing.value.add(item.key);
|
|
|
|
}
|
|
|
|
|
|
|
|
function setAvatar(avatarId) {
|
|
|
|
edits.value.avatar = avatarId;
|
|
|
|
}
|
|
|
|
|
|
|
|
const keyMap = {
|
|
|
|
origin: {
|
|
|
|
country: 'originCountry',
|
|
|
|
state: 'originState',
|
|
|
|
city: 'originCity',
|
|
|
|
},
|
|
|
|
residence: {
|
|
|
|
country: 'residenceCountry',
|
|
|
|
state: 'residenceState',
|
|
|
|
city: 'residenceCity',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
async function submit() {
|
|
|
|
try {
|
|
|
|
await post('/revisions/actors', {
|
|
|
|
actorId: actor.value.id,
|
|
|
|
edits: Object.fromEntries(Array.from(editing.value).flatMap((key) => {
|
|
|
|
if (edits.value[key] && typeof edits.value[key] === 'object') {
|
|
|
|
return Object.entries(edits.value[key]).map(([valueKey, value]) => [keyMap[key]?.[valueKey] || valueKey, value]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return [[key, edits.value[key]]];
|
|
|
|
})),
|
|
|
|
comment: comment.value,
|
|
|
|
apply: apply.value,
|
|
|
|
}, {
|
|
|
|
successFeedback: 'Your revision has been submitted for approval.',
|
|
|
|
appendErrorMessage: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
editing.value = new Set();
|
|
|
|
edits.value = {};
|
|
|
|
comment.value = null;
|
|
|
|
|
|
|
|
submitted.value = true;
|
|
|
|
|
|
|
|
// actor.value = await get(`/actors/${actor.value.id}`);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.editor {
|
|
|
|
flex-grow: 1;
|
|
|
|
background: var(--background-dark-10);
|
|
|
|
}
|
|
|
|
|
|
|
|
.editor-header {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
padding: 1rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.heading {
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
padding: .25rem 1rem;
|
|
|
|
margin-bottom: .25rem;
|
|
|
|
|
|
|
|
&.inline {
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
|
|
& + .inline .key {
|
|
|
|
width: auto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.key {
|
|
|
|
width: 10rem;
|
|
|
|
text-transform: capitalize;
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
.input {
|
|
|
|
background: var(--background);
|
|
|
|
}
|
|
|
|
|
|
|
|
.row .input {
|
|
|
|
height: 2.5rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.select {
|
|
|
|
text-transform: capitalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
.item-header {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.value {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
.input {
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
&:disabled {
|
|
|
|
color: var(--glass-strong-10);
|
|
|
|
background: none;
|
|
|
|
border: solid 1px var(--glass-weak-30);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.duration {
|
|
|
|
.input {
|
|
|
|
width: 5rem;
|
|
|
|
margin-right: .25rem;
|
|
|
|
|
|
|
|
&:not(:first-child) {
|
|
|
|
margin-left: .75rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.number.input {
|
|
|
|
width: 6rem;
|
|
|
|
flex-grow: 0;
|
|
|
|
margin-right: .5rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.disabled {
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.value-section {
|
|
|
|
max-width: 100%;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
}
|
|
|
|
|
|
|
|
.value-label {
|
|
|
|
padding: 0 .25rem;
|
|
|
|
margin-bottom: .25rem;
|
|
|
|
color: var(--shadow-strong-10);
|
|
|
|
font-size: .8rem;
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
.value-divide {
|
|
|
|
padding-right: 1rem;
|
|
|
|
border-right: solid 1px var(--shadow-weak-30);
|
|
|
|
margin-right: .5rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.place,
|
|
|
|
.has,
|
|
|
|
.figure {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
gap: .5rem;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
.figure {
|
|
|
|
.input[type="number"] {
|
|
|
|
width: 5rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.input[type="number"].volume {
|
|
|
|
width: 6rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.figure-bust {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.has {
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
.select {
|
|
|
|
flex-grow: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.description {
|
|
|
|
flex-grow: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.avatars {
|
|
|
|
display: flex;
|
|
|
|
gap: .25rem;
|
|
|
|
padding-bottom: .5rem;
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
|
|
&.disabled {
|
|
|
|
opacity: .5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.item-actions {
|
|
|
|
.icon {
|
|
|
|
padding: .25rem 1rem;
|
|
|
|
fill: var(--glass);
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
cursor: pointer;
|
|
|
|
fill: var(--text);
|
|
|
|
}
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
fill: var(--primary);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.editor-footer {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: center;
|
|
|
|
gap: 1rem;
|
|
|
|
padding: 1rem 1rem 0 1rem;
|
|
|
|
border-top: solid 1px var(--primary-light-30);
|
|
|
|
margin: 1rem 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.comment {
|
|
|
|
width: 100%;
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
.input {
|
|
|
|
width: 100%;
|
|
|
|
resize: vertical;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.editor-actions {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: center;
|
|
|
|
gap: 1.5rem;
|
|
|
|
margin: .5rem 0;
|
|
|
|
|
|
|
|
.button {
|
|
|
|
padding: .5rem 1rem;
|
|
|
|
font-size: 1.1rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.submitted {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: center;
|
|
|
|
padding: 1rem;
|
|
|
|
font-weight: bold;
|
|
|
|
line-height: 1.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media(--small) {
|
|
|
|
.row {
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: stretch;
|
|
|
|
margin-bottom: .25rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.item-header {
|
|
|
|
margin-bottom: .25rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.key {
|
|
|
|
flex-grow: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|