Files
yourpart3/frontend/src/views/social/EroticAccessView.vue

202 lines
5.5 KiB
Vue

<template>
<div class="erotic-access-page">
<section class="erotic-access-hero surface-card">
<span class="erotic-access-eyebrow">{{ $t('socialnetwork.erotic.eyebrow') }}</span>
<h2>{{ $t('socialnetwork.erotic.accessTitle') }}</h2>
<p>{{ $t('socialnetwork.erotic.accessIntro') }}</p>
</section>
<section class="erotic-access-panel surface-card">
<div class="erotic-access-status">
<strong>{{ statusTitle }}</strong>
<span>{{ statusText }}</span>
</div>
<div v-if="account?.adultVerificationRequest" class="erotic-access-request">
<strong>{{ $t('socialnetwork.erotic.requestInfoTitle') }}</strong>
<span>{{ account.adultVerificationRequest.originalName }}</span>
<span v-if="account.adultVerificationRequest.submittedAt">{{ formattedSubmittedAt }}</span>
<span v-if="account.adultVerificationRequest.note">{{ account.adultVerificationRequest.note }}</span>
</div>
<div class="erotic-access-actions">
<router-link to="/settings/account" class="erotic-access-link">
{{ $t('socialnetwork.erotic.settingsLink') }}
</router-link>
</div>
<form v-if="canRequestVerification" class="erotic-access-form" @submit.prevent="requestVerification">
<label>
<span>{{ $t('socialnetwork.erotic.documentLabel') }}</span>
<input type="file" accept=".jpg,.jpeg,.png,.webp,.pdf" @change="handleFileChange" />
</label>
<label>
<span>{{ $t('socialnetwork.erotic.noteLabel') }}</span>
<textarea v-model="note" rows="4"></textarea>
</label>
<button type="submit">{{ $t('socialnetwork.erotic.requestVerification') }}</button>
</form>
</section>
</div>
</template>
<script>
import apiClient from '@/utils/axios.js';
import { mapGetters } from 'vuex';
import { showApiError, showSuccess } from '@/utils/feedback.js';
export default {
name: 'EroticAccessView',
data() {
return {
account: null,
note: '',
documentFile: null
};
},
computed: {
...mapGetters(['user']),
status() {
return this.account?.adultVerificationStatus || 'none';
},
canRequestVerification() {
return this.account?.isAdult && ['none', 'rejected'].includes(this.status);
},
statusTitle() {
if (!this.account?.isAdult) {
return this.$t('settings.account.adultStatus.ineligible.title');
}
return this.$t(`socialnetwork.erotic.status.${this.status}.title`);
},
statusText() {
if (!this.account?.isAdult) {
return this.$t('settings.account.adultStatus.ineligible.body');
}
return this.$t(`socialnetwork.erotic.status.${this.status}.body`);
},
formattedSubmittedAt() {
const value = this.account?.adultVerificationRequest?.submittedAt;
if (!value) return '';
return new Date(value).toLocaleString();
}
},
methods: {
async loadAccount() {
const response = await apiClient.post('/api/settings/account', { userId: this.user.id });
this.account = response.data;
},
handleFileChange(event) {
this.documentFile = event.target.files?.[0] || null;
},
async requestVerification() {
try {
const formData = new FormData();
if (this.documentFile) {
formData.append('document', this.documentFile);
}
formData.append('note', this.note || '');
await apiClient.post('/api/settings/adult-verification/request', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
await this.loadAccount();
this.note = '';
this.documentFile = null;
showSuccess(this, this.$t('socialnetwork.erotic.requestSent'));
} catch (error) {
showApiError(this, error, this.$t('socialnetwork.erotic.requestError'));
}
}
},
async mounted() {
await this.loadAccount();
if (this.account?.adultAccessEnabled) {
this.$router.replace('/socialnetwork/erotic/pictures');
}
}
};
</script>
<style lang="scss" scoped>
.erotic-access-page {
display: grid;
gap: 18px;
max-width: 920px;
}
.erotic-access-hero,
.erotic-access-panel {
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: linear-gradient(180deg, rgba(255, 249, 244, 0.98), rgba(245, 237, 229, 0.96));
box-shadow: var(--shadow-soft);
}
.erotic-access-hero {
padding: 26px 28px;
}
.erotic-access-eyebrow {
display: inline-flex;
margin-bottom: 8px;
padding: 4px 10px;
border-radius: var(--radius-pill);
background: rgba(164, 98, 72, 0.14);
color: var(--color-text-secondary);
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.erotic-access-hero p {
margin: 0;
color: var(--color-text-secondary);
}
.erotic-access-panel {
display: grid;
gap: 18px;
padding: 24px;
}
.erotic-access-status {
display: grid;
gap: 6px;
padding: 14px 16px;
border-radius: var(--radius-md);
background: rgba(196, 162, 108, 0.14);
}
.erotic-access-request,
.erotic-access-form {
display: grid;
gap: 10px;
}
.erotic-access-request {
padding: 14px 16px;
border-radius: var(--radius-md);
background: rgba(255, 255, 255, 0.6);
color: var(--color-text-secondary);
}
.erotic-access-actions {
display: flex;
gap: 12px;
flex-wrap: wrap;
align-items: center;
}
.erotic-access-link {
color: var(--color-primary);
font-weight: 600;
}
.erotic-access-form label {
display: grid;
gap: 6px;
}
</style>