Compare commits

...

3 Commits

Author SHA1 Message Date
Alex Ant 3632bea54e chore(release): publish
- terminal@0.1.32
2024-07-31 17:26:08 +05:00
Alex Ant 7d6266c241 chore(release): publish
- terminal@0.1.32-alpha.0
2024-07-31 16:28:53 +05:00
Alex Ant 1d69b9ffea Рабочие столы v1 2024-07-31 16:24:50 +05:00
50 changed files with 975 additions and 379 deletions
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.1.32](https://github.com/coopenomics/monocoop/compare/terminal@0.1.32-alpha.0...terminal@0.1.32) (2024-07-31)
**Note:** Version bump only for package terminal
## [0.1.31](https://github.com/coopenomics/monocoop/compare/terminal@0.1.31-alpha.0...terminal@0.1.31) (2024-07-26)
**Note:** Version bump only for package terminal
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "terminal",
"version": "0.1.31",
"version": "0.1.32",
"description": "A Terminal Project",
"productName": "Terminal App",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
+2
View File
@@ -102,6 +102,7 @@ module.exports = configure(function (/* ctx */) {
eslint: {
lintCommand: 'eslint "./**/*.{js,ts,mjs,cjs,vue}"',
},
overlay: false
},
{ server: false },
],
@@ -111,6 +112,7 @@ module.exports = configure(function (/* ctx */) {
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
devServer: {
// https: true
vueDevtools: false,
open: false, // opens browser window automatically
port: 3005,
hmr:{
@@ -0,0 +1,136 @@
import { defineStore } from 'pinia'
import * as Desktops from 'src/desktops'
import { computed, ComputedRef, ref, Ref } from 'vue'
import { FailAlert } from 'src/shared/api'
import { RouteRecordRaw, type RouteLocationNormalized} from 'vue-router'
interface IDesktop {
name: string
hash: string
authorizedHome: string
nonAuthorizedHome: string
routes: IRoute[]
config: object
}
interface IBlockchainDesktops {
defaultHash: string //hash
availableHashes: string[] //hashes
}
interface RouteMeta {
title: string;
icon: string;
roles: string[];
}
export interface IRoute {
path: string;
name: string;
component?: any;
children?: IRoute[];
meta: RouteMeta;
}
const desktopHashMap = {
'hash1': Desktops.UserDesktopModel.manifest, //User
'hash2': Desktops.ChairmanDesktopModel.manifest, //'Chairman',
'hash3': Desktops.MemberDesktopModel.manifest, //'Member',
'hash4': Desktops.SetupDesktopModel.manifest, //Setup
}
const namespace = 'desktops';
interface IDesktopStore {
currentDesktop: Ref<IDesktop | undefined>
availableDesktops: Ref<IDesktop[]>
defaultDesktopHash: Ref<string | undefined>
setActiveDesktop: (hash: string | undefined) => void;
loadDesktops: () => void;
getSecondLevel: (currentRoute: RouteLocationNormalized) => RouteRecordRaw[]
firstLevel: ComputedRef<IRoute[]>;
// secondLevel: ComputedRef<IRoute[]>;
}
function getNestedRoutes(route: RouteRecordRaw):RouteRecordRaw[] {
if (!route.children) {
return [];
}
let nestedRoutes: RouteRecordRaw[] = [];
for (const child of route.children) {
nestedRoutes.push(child);
nestedRoutes = nestedRoutes.concat(getNestedRoutes(child));
}
return nestedRoutes;
}
export const useDesktopStore = defineStore(namespace, (): IDesktopStore => {
const currentDesktop = ref<IDesktop>()
const availableDesktops = ref<IDesktop[]>([])
const defaultDesktopHash = ref<string>()
const firstLevel = computed(() => {
if (currentDesktop.value)
return currentDesktop.value.routes
else return []
});
const getSecondLevel = (currentRoute: RouteLocationNormalized): RouteRecordRaw[] => {
if (currentRoute.matched && currentDesktop.value && currentRoute) {
const matchingRootRoute = currentRoute.matched[1]
if (matchingRootRoute) {
return getNestedRoutes(matchingRootRoute)
}
}
return [];
}
const setActiveDesktop = (hash: string | undefined) => {
const desktop = availableDesktops.value.find(d => d.hash === hash)
if (desktop)
currentDesktop.value = desktop
else {
FailAlert('Рабочий стол не найден')
}
}
const loadAvailableDesktops = async(): Promise<IBlockchainDesktops> => {
return { //load it from bc later
defaultHash: 'hash1',
availableHashes: ['hash1','hash2', 'hash3']
}
}
const loadDesktops = async () => {
const {defaultHash, availableHashes} = await loadAvailableDesktops()
availableDesktops.value = []
defaultDesktopHash.value = defaultHash
availableHashes.map(hash => availableDesktops.value.push(
desktopHashMap[hash as keyof typeof desktopHashMap]
))
}
return {
defaultDesktopHash, //перезапишем через локал-сторадж для пользовательского управления стартовой страницей
currentDesktop,
availableDesktops,
setActiveDesktop,
loadDesktops,
getSecondLevel,
firstLevel,
}
})
+17 -11
View File
@@ -1,6 +1,7 @@
import { route } from 'quasar/wrappers';
import {
RouteLocationNormalizedGeneric,
RouteRecordRaw,
createMemoryHistory,
createRouter,
createWebHashHistory,
@@ -9,20 +10,30 @@ import {
import { routes } from 'src/app/providers/routes';
import { useSessionStore } from 'src/entities/Session';
import {
AUTHORIZED_HOME_PAGE,
COOPNAME,
NOT_AUTHORIZED_HOME_PAGE,
} from 'src/shared/config';
import { IUserAccountData, useCurrentUserStore } from 'src/entities/User';
import { useMenuStore } from 'src/entities/Menu';
import { useDesktopStore } from './desktops';
export default route(function (/* { store, ssrContext } */) {
export const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
export default route(async function (/* { store, ssrContext } */) {
const createHistory = process.env.SERVER
? createMemoryHistory
: process.env.VUE_ROUTER_MODE === 'history'
? createWebHistory
: createWebHashHistory;
const desktops = useDesktopStore()
await desktops.loadDesktops()
await desktops.setActiveDesktop(desktops.defaultDesktopHash)
desktops.currentDesktop?.routes.forEach(route => {
routes[0].children?.push(route as RouteRecordRaw)
})
const router = createRouter({
history: createHistory(process.env.VUE_ROUTER_BASE),
routes,
@@ -57,20 +68,15 @@ export default route(function (/* { store, ssrContext } */) {
} catch(e: any){
console.error(e)
}
}
const menuStore = useMenuStore()
menuStore.setRoutes(routes)
if (to.name == 'index') {
console.log('7')
if (session.isAuth){
next({ name: AUTHORIZED_HOME_PAGE, params: { coopname: COOPNAME } });
next({ name: desktops.currentDesktop?.authorizedHome, params: { coopname: COOPNAME } });
return
} else {
next({
name: NOT_AUTHORIZED_HOME_PAGE,
name: desktops.currentDesktop?.nonAuthorizedHome,
params: { coopname: COOPNAME },
});
return;
@@ -2,24 +2,10 @@ import layout from 'src/pages/_layouts/default.vue';
import index from 'src/pages/index.vue';
import blank from 'src/pages/blank/blank.vue';
import permissionDenied from 'src/pages/_layouts/permissionDenied.vue';
// import sovietPage from 'src/components/soviet/index.vue'
import { CoopSettingsPage } from 'src/pages/CoopSettings';
import { UserHomePage } from 'src/pages/UserHome/ui';
import { ModerationPage } from 'src/pages/marketplace/Moderation';
import { CreateParentOfferPage } from 'src/pages/marketplace/CreateParentOffer';
import { ShowcasePage } from 'src/pages/marketplace/Showcase';
import { SuppliesListPage } from 'src/pages/marketplace/SuppliesList';
import { UserParentOffersPage } from 'src/pages/marketplace/UserParentOffers';
import { UserSuppliesListPage } from 'src/pages/marketplace/UserSuppliesList';
import { MainMarketplacePage } from 'src/pages/marketplace/MainPage';
import { SignUpPage } from 'src/pages/SignUp';
import { SignInPage } from 'src/pages/SignIn';
import { RouteRecordRaw } from 'vue-router';
import decisions from 'src/components/soviet/decisions.vue';
import participants from 'src/components/soviet/participants.vue';
import documents from 'src/components/soviet/documents.vue';
import { ContactsPage } from 'src/pages/Contacts';
const baseRoutes = [
{
@@ -31,66 +17,15 @@ const baseRoutes = [
name: 'index',
component: index,
},
//страница кошелька пользователя
{
path: '/:coopname/home',
name: 'home',
component: UserHomePage,
children: [],
meta: {
is_desktop_menu: true,
title: 'Профиль',
icon: 'fa-solid fa-id-card',
roles: [],
},
},
//страница управления кооперативом
{
path: ':coopname/settings',
name: 'soviet',
component: CoopSettingsPage,
meta: {
is_desktop_menu: true,
title: 'Настройки',
icon: 'fa-solid fa-cog',
roles: ['chairman', 'member'],
},
path: '/something-bad',
name: 'somethingBad',
component: blank,
},
{
path: ':coopname/agenda',
name: 'agenda',
component: decisions,
meta: {
is_desktop_menu: true,
title: 'Повестка',
icon: 'fa-solid fa-check-to-slot',
roles: ['chairman', 'member'],
},
},
{
path: ':coopname/participants',
name: 'participants',
component: participants,
meta: {
is_desktop_menu: true,
title: 'Пайщики',
icon: 'fa-solid fa-users',
roles: ['chairman', 'member'],
},
},
{
path: ':coopname/documents',
name: 'documents',
component: documents,
meta: {
is_desktop_menu: true,
title: 'Документы',
icon: 'fa-solid fa-file-invoice',
roles: ['chairman', 'member'],
},
path: '/permission-denied',
name: 'permissionDenied',
component: permissionDenied,
},
{
path: ':coopname/auth/signin',
@@ -104,80 +39,6 @@ const baseRoutes = [
component: SignUpPage,
children: [],
},
{
path: '/:coopname/marketplace',
name: 'marketplace',
component: MainMarketplacePage,
children: [
{
path: 'moderation',
name: 'marketplace-moderation',
component: ModerationPage,
},
{
path: 'create-offer',
name: 'marketplace-create-offer',
component: CreateParentOfferPage,
},
{
path: 'showcase',
name: 'marketplace-showcase',
component: ShowcasePage,
children: [
{
path: ':id',
name: 'marketplace-showcase-id',
component: ShowcasePage,
},
],
},
{
path: 'user-offers',
name: 'marketplace-user-offers',
component: UserParentOffersPage,
children: [
{
path: ':id',
name: 'marketplace-user-offer-id',
component: UserParentOffersPage,
},
],
},
{
path: 'supplies',
name: 'marketplace-supplies',
component: SuppliesListPage,
},
{
path: 'user-supplies',
name: 'marketplace-user-supplies',
component: UserSuppliesListPage,
},
],
},
//страница контактов
{
path: ':coopname/contacts',
name: 'contacts',
component: ContactsPage,
meta: {
is_desktop_menu: true,
title: 'Контакты',
icon: 'fa-solid fa-info',
roles: [],
},
},
{
path: '/something-bad',
name: 'somethingBad',
component: blank,
},
{
path: '/permission-denied',
name: 'permissionDenied',
component: permissionDenied,
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
@@ -187,6 +48,109 @@ const baseRoutes = [
},
];
// const baseRoutes = [
// {
// path: '/',
// component: layout,
// children: [
// {
// path: '',
// name: 'index',
// component: index,
// },
// //страница кошелька пользователя
// {
// path: '/:coopname/home',
// name: 'home',
// component: UserHomePage,
// children: [],
// meta: {
// is_desktop_menu: true,
// title: 'Профиль',
// icon: 'fa-solid fa-id-card',
// roles: [],
// },
// },
// //страница управления кооперативом
// {
// path: ':coopname/settings',
// name: 'soviet',
// component: CoopSettingsPage,
// meta: {
// is_desktop_menu: true,
// title: 'Настройки',
// icon: 'fa-solid fa-cog',
// roles: ['chairman', 'member'],
// },
// },
// {
// path: ':coopname/agenda',
// name: 'agenda',
// component: decisions,
// meta: {
// is_desktop_menu: true,
// title: 'Повестка',
// icon: 'fa-solid fa-check-to-slot',
// roles: ['chairman', 'member'],
// },
// },
// {
// path: ':coopname/participants',
// name: 'participants',
// component: participants,
// meta: {
// is_desktop_menu: true,
// title: 'Пайщики',
// icon: 'fa-solid fa-users',
// roles: ['chairman', 'member'],
// },
// },
// {
// path: ':coopname/documents',
// name: 'documents',
// component: documents,
// meta: {
// is_desktop_menu: true,
// title: 'Документы',
// icon: 'fa-solid fa-file-invoice',
// roles: ['chairman', 'member'],
// },
// },
// {
// path: ':coopname/auth/signin',
// name: 'signin',
// component: SignInPage,
// children: [],
// },
// {
// path: ':coopname/auth/signup',
// name: 'signup',
// component: SignUpPage,
// children: [],
// },
// {
// path: '/something-bad',
// name: 'somethingBad',
// component: blank,
// },
// {
// path: '/permission-denied',
// name: 'permissionDenied',
// component: permissionDenied,
// },
// {
// path: '/:pathMatch(.*)*',
// name: 'NotFound',
// component: blank,
// },
// ],
// },
// ];
const rs = baseRoutes;
export const routes = rs as RouteRecordRaw[];
@@ -1,37 +1,36 @@
<template lang="pug">
div.menu-container
div.menu-items
div(v-for="route in menuRoutes" :key="route.path")
q-btn(
v-ripple
flat
class="cursor-pointer btn-menu"
:class="headerClass(route)"
@click="open(route)"
)
q-icon(:name="route.meta.icon").btn-icon.q-pt-xs
span.btn-font {{ t(route.meta.title) }}
q-btn(
v-for="route in menuRoutes" :key="route.path"
v-ripple
flat
class="cursor-pointer btn-menu"
:class="headerClass(route)"
@click="open(route)"
)
q-icon(:name="route.meta.icon").btn-icon.q-pt-xs
span.btn-font {{ route.meta.title }}
div.control-buttons
div
q-btn(flat @click="$q.dark.toggle()").btn-menu
q-icon(:name="isDark ? 'brightness_7' : 'brightness_3'").btn-icon
span.btn-font {{ isDark ? 'светлая' : 'тёмная' }}
div
q-btn(v-ripple flat class="cursor-pointer btn-menu" @click="logout")
q-icon( color="red" name="logout").btn-icon.q-pt-xs
div.btn-font Выход
q-btn(flat @click="$q.dark.toggle()" ).btn-menu
q-icon(:name="isDark ? 'brightness_7' : 'brightness_3'").q-pt-xs.btn-icon
span.btn-font {{ isDark ? 'светлая' : 'тёмная' }}
q-btn(v-ripple flat class="cursor-pointer btn-menu" @click="logout")
q-icon( color="red" name="logout").q-pt-xs.btn-icon
div.btn-font Выход
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useQuasar } from 'quasar'
import { useMenuStore } from 'src/entities/Menu'
import type { IMenu } from 'src/entities/Menu'
import { COOPNAME } from 'src/shared/config'
import { useLogoutUser } from 'src/features/User/Logout/model'
import { type IRoute, useDesktopStore } from 'src/app/providers/desktops'
import { useLogoutUser } from 'src/features/User/Logout'
import { FailAlert } from 'src/shared/api'
import { useCurrentUserStore } from 'src/entities/User'
@@ -41,27 +40,24 @@ const isDark = computed(() => $q.dark.isActive)
const router = useRouter()
const route = useRoute()
const user = useCurrentUserStore()
const isRouteActive = (currentRoute: IMenu) => {
return route.name === currentRoute.name
const isRouteActive = (currentRoute: IRoute) => {
return route.matched.find(r => r.path === currentRoute.path) || route.name == currentRoute.name
}
const headerClass = (route: IMenu) => {
const headerClass = (route: IRoute) => {
const isActive = isRouteActive(route)
return isActive ? (isDark.value ? 'text-white bg-teal-8' : 'text-black bg-teal-2') : ''
}
const currentUser = useCurrentUserStore()
const menuStore = useMenuStore()
const desktop = useDesktopStore()
const { t } = useI18n()
const open = (route: IRoute) => {
if (route.children)
router.push({ name: route.children[0].name, params: { coopname: COOPNAME } })
else router.push({ name: route.name, params: { coopname: COOPNAME } })
const menu = ref<IMenu[]>([])
menu.value = menuStore.getUserDesktopMenu(currentUser?.userAccount?.role)
const open = (route: IMenu) => {
router.push({ name: route.name, params: { coopname: COOPNAME } })
}
@@ -78,15 +74,23 @@ const logout = async () => {
}
}
const menuRoutes = computed(() => {
return menu.value
const userRole = user.userAccount?.role || 'user';
return desktop.firstLevel.filter(
(route) => route.meta.roles.includes(userRole) || route.meta.roles.length === 0
);
})
</script>
<style lang="scss" scoped>
.btn-menu {
height: 70px;
width: 70px;
height: 54px;
width: 65px;
}
.btn-icon {
@@ -99,13 +103,13 @@ const menuRoutes = computed(() => {
.logout-btn {
position: fixed;
bottom: 70px;
bottom: 54px;
width: 100%;
}
.menu-container {
display: flex;
flex-direction: column;
// flex-direction: column;
height: 100%;
}
@@ -1,77 +1,76 @@
<template lang="pug">
div.row.justify-center
div.col-12
q-card(flat)
q-table(
ref="tableRef" v-model:expanded="expanded"
flat
bordered
:rows="decisions"
:columns="columns"
:table-colspan="9"
row-key="table.id"
:pagination="pagination"
virtual-scroll
:virtual-scroll-item-size="48"
:rows-per-page-options="[10]"
:loading="onLoading"
:no-data-label="'У совета нет голосований на повестке'"
).full-height.full-width
template(#header="props")
q-tr(:props="props")
q-th(auto-width)
q-card(flat)
q-table(
ref="tableRef" v-model:expanded="expanded"
flat
bordered
:rows="decisions"
:columns="columns"
:table-colspan="9"
row-key="table.id"
:pagination="pagination"
virtual-scroll
:virtual-scroll-item-size="48"
:rows-per-page-options="[10]"
:loading="onLoading"
:no-data-label="'У совета нет голосований на повестке'"
).full-width
q-th(
v-for="col in props.cols"
:key="col.name"
:props="props"
) {{ col.label }}
template(#header="props")
q-tr(:props="props")
q-th(auto-width)
template(#body="props")
q-tr(:key="`m_${props.row.table.id}`" :props="props")
q-td(auto-width)
// q-toggle(v-model="props.expand" checked-icon="fas fa-chevron-circle-left" unchecked-icon="fas fa-chevron-circle-right" )
q-th(
v-for="col in props.cols"
:key="col.name"
:props="props"
) {{ col.label }}
q-btn(size="sm" color="primary" dense :icon="props.expand ? 'remove' : 'add'" round @click="props.expand = !props.expand")
q-td {{ props.row.table.id }}
q-td {{ props.row.table.username }}
q-td
q-badge {{ getTitle(props.row.table.type, props.row.documents.statement.action.user) }}
template(#body="props")
q-tr(:key="`m_${props.row.table.id}`" :props="props")
q-td(auto-width)
// q-toggle(v-model="props.expand" checked-icon="fas fa-chevron-circle-left" unchecked-icon="fas fa-chevron-circle-right" )
//- q-td
//- q-checkbox(@click="updateValidation(props.row.id)" :model-value="props.row.validated")
q-btn(size="sm" color="primary" dense :icon="props.expand ? 'remove' : 'add'" round @click="props.expand = !props.expand")
q-td {{ props.row.table.id }}
q-td {{ props.row.table.username }}
q-td
q-badge {{ getTitle(props.row.table.type, props.row.documents.statement.action.user) }}
q-td
//- p Проголосовало {{ props.row.table.votes_for.length + props.row.table.votes_against.length}} из {{totalMembers}}
//- q-td
//- q-checkbox(@click="updateValidation(props.row.id)" :model-value="props.row.validated")
q-td
//- p Проголосовало {{ props.row.table.votes_for.length + props.row.table.votes_against.length}} из {{totalMembers}}
q-btn(v-if="isVotedFor(props.row.table) || !isVotedAny(props.row.table)" :disabled="isVotedAny(props.row.table)" dense flat @click="voteAgainst(props.row.table.id)").text-red
q-icon(name="fa-regular fa-thumbs-down")
p.q-pl-xs {{props.row.table.votes_against.length}}
q-btn(v-if="isVotedFor(props.row.table) || !isVotedAny(props.row.table)" :disabled="isVotedAny(props.row.table)" dense flat @click="voteAgainst(props.row.table.id)").text-red
q-icon(name="fa-regular fa-thumbs-down")
p.q-pl-xs {{props.row.table.votes_against.length}}
q-btn(v-if="isVotedAgainst(props.row.table)" disabled dense flat).text-red
q-icon(name="fas fa-thumbs-down")
p.q-pl-xs {{props.row.table.votes_against.length}}
q-btn(v-if="isVotedAgainst(props.row.table)" disabled dense flat).text-red
q-icon(name="fas fa-thumbs-down")
p.q-pl-xs {{props.row.table.votes_against.length}}
q-checkbox( v-model="props.row.table.approved" disable :true-value="1" :false-value="0" )
q-checkbox( v-model="props.row.table.approved" disable :true-value="1" :false-value="0" )
q-btn(v-if="isVotedAgainst(props.row.table) || !isVotedAny(props.row.table)" :disabled="isVotedAny(props.row.table)" dense flat @click="voteFor(props.row.table.id)").text-green
p.q-pr-xs {{props.row.table.votes_for.length}}
q-icon(name="fa-regular fa-thumbs-up" style="transform: scaleX(-1)")
q-btn(v-if="isVotedAgainst(props.row.table) || !isVotedAny(props.row.table)" :disabled="isVotedAny(props.row.table)" dense flat @click="voteFor(props.row.table.id)").text-green
p.q-pr-xs {{props.row.table.votes_for.length}}
q-icon(name="fa-regular fa-thumbs-up" style="transform: scaleX(-1)")
q-btn(v-if="isVotedFor(props.row.table)" disabled dense flat ).text-green
p.q-pr-xs {{props.row.table.votes_for.length}}
q-icon(name="fas fa-thumbs-up" style="transform: scaleX(-1)")
q-btn(v-if="isVotedFor(props.row.table)" disabled dense flat ).text-green
p.q-pr-xs {{props.row.table.votes_for.length}}
q-icon(name="fas fa-thumbs-up" style="transform: scaleX(-1)")
q-td
q-btn( :loading="isProcess(props.row.table.id)" @click="updateAuthorized(props.row.table.username, props.row.table.id)") утвердить
//- q-checkbox(v-if="!isProcess(props.row.table.id)" :model-value="props.row.table.authorized" :true-value="1" :false-value="0" @click="updateAuthorized(props.row.table.username, props.row.table.id)")
//- q-spinner(v-if="isProcess(props.row.table.id)" size="md")
q-td
q-btn( :loading="isProcess(props.row.table.id)" @click="updateAuthorized(props.row.table.username, props.row.table.id)") утвердить
//- q-checkbox(v-if="!isProcess(props.row.table.id)" :model-value="props.row.table.authorized" :true-value="1" :false-value="0" @click="updateAuthorized(props.row.table.username, props.row.table.id)")
//- q-spinner(v-if="isProcess(props.row.table.id)" size="md")
q-tr(v-show="props.expand" :key="`e_${props.row.table.id}`" :props="props" class="q-virtual-scroll--with-prev")
q-td(colspan="100%")
joincoopdoc(v-if="props.row.table.type == 'joincoop'" :documents="props.row.documents")
q-tr(v-show="props.expand" :key="`e_${props.row.table.id}`" :props="props" class="q-virtual-scroll--with-prev")
q-td(colspan="100%")
joincoopdoc(v-if="props.row.table.type == 'joincoop'" :documents="props.row.documents")
@@ -0,0 +1 @@
export * as ChairmanDesktopModel from './model'
@@ -0,0 +1,30 @@
import { UserHomePage } from 'src/pages/UserHome';
export const manifest = {
'name': 'ChairmanDesktop',
'hash': 'hash2',
'authorizedHome': 'home',
'nonAuthorizedHome': 'signup',
'routes': [
{
path: '/:coopname/home',
name: 'home',
component: UserHomePage,
children: [],
meta: {
is_desktop_menu: true,
title: 'Профиль',
icon: 'fa-solid fa-id-card',
roles: [],
},
},
],
'config': {
'layout': 'default',
'theme': 'light'
},
'schemas': {
'layout': 'avj schema here',
'theme': 'avj schema here'
}
}
@@ -0,0 +1 @@
export * as MemberDesktopModel from './model'
@@ -0,0 +1,30 @@
import { UserHomePage } from 'src/pages/UserHome';
export const manifest = {
'name': 'ChairmanDesktop',
'hash': 'hash2',
'authorizedHome': 'home',
'nonAuthorizedHome': 'signup',
'routes': [
{
path: '/:coopname/home',
name: 'home',
component: UserHomePage,
children: [],
meta: {
is_desktop_menu: true,
title: 'Профиль',
icon: 'fa-solid fa-id-card',
roles: [],
},
},
],
'config': {
'layout': 'default',
'theme': 'light'
},
'schemas': {
'layout': 'avj schema here',
'theme': 'avj schema here'
}
}
@@ -0,0 +1 @@
export * as SetupDesktopModel from './model'
@@ -0,0 +1,30 @@
import { UserHomePage } from 'src/pages/UserHome';
export const manifest = {
'name': 'ChairmanDesktop',
'hash': 'hash2',
'authorizedHome': 'home',
'nonAuthorizedHome': 'signup',
'routes': [
{
path: '/:coopname/home',
name: 'home',
component: UserHomePage,
children: [],
meta: {
is_desktop_menu: true,
title: 'Профиль',
icon: 'fa-solid fa-id-card',
roles: [],
},
},
],
'config': {
'layout': 'default',
'theme': 'light'
},
'schemas': {
'layout': 'avj schema here',
'theme': 'avj schema here'
}
}
@@ -0,0 +1 @@
export * as UserDesktopModel from './model'
@@ -0,0 +1,289 @@
import { UserIdentityPage } from 'src/pages/User/IdentityPage';
import { UserPaymentMethodsPage } from 'src/pages/User/PaymentMethodsPage';
import { UserWalletPage } from 'src/pages/User/WalletPage';
import decisions from 'src/components/soviet/decisions.vue';
import participants from 'src/components/soviet/participants.vue';
import documents from 'src/components/soviet/documents.vue';
import { markRaw } from 'vue';
// import { Commutator } from 'src/widgets/Commutator';
// import { MainMarketplacePage } from 'src/pages/marketplace/MainPage';
// import { ModerationPage } from 'src/pages/marketplace/Moderation';
// import { CreateParentOfferPage } from 'src/pages/marketplace/CreateParentOffer';
// import { ShowcasePage } from 'src/pages/marketplace/Showcase';
// import { UserParentOffersPage } from 'src/pages/marketplace/UserParentOffers';
// import { SuppliesListPage } from 'src/pages/marketplace/SuppliesList';
// import { UserSuppliesListPage } from 'src/pages/marketplace/UserSuppliesList';
import { ContactsPage } from 'src/pages/Contacts';
import { CooperativeDetails } from 'src/widgets/Cooperative/Details';
import { CooperativeMembers } from 'src/widgets/Cooperative/Members';
import { ChangeCooperativeContributions } from 'src/widgets/Cooperative/Contributions';
import { ChangeCooperativeContacts } from 'src/widgets/Cooperative/Contacts';
export const manifest = {
'name': 'UserDesktop',
'hash': 'hash1',
'authorizedHome': 'user-identity',
'nonAuthorizedHome': 'signin',
'routes': [
{
meta: {
title: 'Пайщик',
icon: 'fa-solid fa-id-card',
roles: [],
},
path: '/:coopname/user',
name: 'home',
// component: markRaw(UserHomePage),
children: [{
meta: {
title: 'Удостоверение',
icon: '',
roles: [],
},
path: 'identity',
name: 'user-identity',
component: markRaw(UserIdentityPage),
children: [],
},{
meta: {
title: 'Кошелёк',
icon: '',
roles: [],
},
path: 'wallet',
name: 'user-wallet',
component: markRaw(UserWalletPage),
children: [],
},
{
meta: {
title: 'Реквизиты',
icon: '',
roles: [],
},
path: 'payment-methods',
name: 'user-payment-methods',
component: markRaw(UserPaymentMethodsPage),
children: [],
}
],
},
{
meta: {
title: 'Совет',
icon: 'fa-regular fa-circle',
roles: ['chairman', 'member'],
},
path: '/:coopname/soviet',
name: 'soviet',
children: [
{
path: 'agenda',
name: 'agenda',
component: markRaw(decisions),
meta: {
title: 'Повестка',
icon: 'fa-solid fa-check-to-slot',
roles: [],
},
},
{
path: 'participants',
name: 'participants',
component: markRaw(participants),
meta: {
title: 'Пайщики',
icon: 'fa-solid fa-users',
roles: ['chairman', 'member'],
},
},
{
path: 'documents',
name: 'documents',
component: markRaw(documents),
meta: {
title: 'Документы',
icon: 'fa-solid fa-file-invoice',
roles: ['chairman', 'member'],
},
},
]
},
//КООПЕРАТИВ
{
meta: {
title: 'Кооператив',
icon: 'fa-solid fa-cog',
roles: ['chairman', 'member'],
},
path: '/:coopname/settings',
name: 'settings',
children: [
{
path: 'details',
name: 'settings-details',
component: markRaw(CooperativeDetails),
meta: {
title: 'Реквизиты',
icon: 'fa-solid fa-check-to-slot',
roles: [],
},
},
{
path: 'members',
name: 'settings-members',
component: markRaw(CooperativeMembers),
meta: {
title: 'Члены Совета',
icon: 'fa-solid fa-users',
roles: ['chairman', 'member'],
},
},
{
path: 'contributions',
name: 'settings-contributions',
component: markRaw(ChangeCooperativeContributions),
meta: {
title: 'Взносы',
icon: 'fa-solid fa-file-invoice',
roles: ['chairman', 'member'],
},
},
{
path: 'contacts',
name: 'settings-contacts',
component: markRaw(ChangeCooperativeContacts),
meta: {
title: 'Контакты',
icon: 'fa-solid fa-file-invoice',
roles: ['chairman', 'member'],
},
},
]
},
// //страница управления кооперативом
// {
// meta: {
// title: 'Маркетплейс',
// icon: 'fa-solid fa-cog',
// roles: [],
// },
// path: '/:coopname/marketplace',
// name: 'marketplace',
// component: markRaw(MainMarketplacePage),
// children: [
// {
// path: 'moderation',
// name: 'marketplace-moderation',
// component: markRaw(ModerationPage),
// meta: {
// title: 'Модерация',
// icon: '',
// roles: ['member', 'chairman'],
// },
// },
// {
// path: 'create-offer',
// name: 'marketplace-create-offer',
// component: markRaw(CreateParentOfferPage),
// meta: {
// title: 'Создать объявление',
// icon: '',
// roles: [],
// },
// },
// {
// path: 'showcase',
// name: 'marketplace-showcase',
// component: markRaw(ShowcasePage),
// children: [
// {
// path: ':id',
// name: 'marketplace-showcase-id',
// component: markRaw(ShowcasePage),
// },
// ],
// meta: {
// title: 'Витрина',
// icon: '',
// roles: [],
// },
// },
// {
// path: 'user-offers',
// name: 'marketplace-user-offers',
// component: markRaw(UserParentOffersPage),
// children: [
// {
// path: ':id',
// name: 'marketplace-user-offer-id',
// component: markRaw(UserParentOffersPage),
// },
// ],
// meta: {
// title: 'Мои объявления',
// icon: '',
// roles: [],
// },
// },
// {
// path: 'supplies',
// name: 'marketplace-supplies',
// component: markRaw(SuppliesListPage),
// meta: {
// title: 'Все заказы',
// icon: '',
// roles: ['member', 'chairman'],
// },
// },
// {
// path: 'user-supplies',
// name: 'marketplace-user-supplies',
// component: markRaw(UserSuppliesListPage),
// meta: {
// title: 'Мои заказы',
// icon: '',
// roles: [],
// },
// },
// ],
// },
//страница контактов
{
path: ':coopname/contacts',
name: 'contacts',
component: markRaw(ContactsPage),
meta: {
title: 'Контакты',
icon: 'fa-solid fa-info',
roles: [],
},
},
// {
// path: ':coopname/commutator',
// name: 'commutator',
// component: markRaw(Commutator),
// meta: {
// title: 'Коммутатор',
// icon: '',
// roles: [],
// },
// },
],
'config': {
'layout': 'default',
'theme': 'light'
},
'schemas': {
'layout': 'avj schema here',
'theme': 'avj schema here'
}
}
@@ -0,0 +1,9 @@
export * from './Chairman'
export * from './Member'
export * from './User'
export * from './Setup'
// export desktopsMap {
// Chairman: ChairmanDesktop,
// }
@@ -0,0 +1 @@
export * from './ui'
@@ -0,0 +1,5 @@
<template lang="pug">
div menu
</template>
<script lang="ts" setup>
</script>
@@ -0,0 +1 @@
export {default as FirstLevelMenu} from './FirstLevelMenu.vue'
@@ -0,0 +1,50 @@
<template lang="pug">
q-tabs(
v-if="routes"
dense
switch-indicator
inline-label
outside-arrows
mobile-arrows
align="justify"
active-class="bg-teal"
active-bg-color="teal"
active-color="white"
indicator-color="secondary"
)
q-route-tab(
v-for="route in routes"
:key="route.name"
:name="route.meta.title"
:label="route.meta.title"
:to="{ name: route.name }"
:params="{coopname: 'voskhod'}"
)
</template>
<script lang="ts" setup>
import { type IRoute, useDesktopStore } from 'src/app/providers/desktops';
import { useCurrentUserStore } from 'src/entities/User';
import { ref, watch } from 'vue';
import { useRoute } from 'vue-router';
const desktop = useDesktopStore()
const routes = ref<IRoute[]>([])
const route = useRoute()
const user = useCurrentUserStore()
const init = () => {
const userRole = user.userAccount?.role || 'user';
routes.value = (desktop.getSecondLevel(route) as unknown as IRoute[]).filter(
(route) => route.meta?.roles?.includes(userRole) || route.meta?.roles?.length === 0
);
}
init()
watch(route, () => init())
</script>
@@ -0,0 +1 @@
export {default as SecondLevelMenu} from './SecondLevelMenu.vue'
@@ -0,0 +1,2 @@
export * from './FirstLevelMenu'
export * from './SecondLevelMenu'
@@ -77,7 +77,7 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
const createDeposit = async (
params: ICreateDeposit
): Promise<IPaymentOrder> => {
return sendPOST('/v1/orders/deposit', params);
return sendPOST('/v1/payments/deposit', params);
};
const createWithdraw = async (params: ICreateWithdraw): Promise<void> => {
@@ -4,13 +4,13 @@ const walletStore = useWalletStore()
</script>
<template lang="pug">
div.row.flex.justify-around.q-pa-sm
div.q-mt-md
span.text-grey Паевый счёт
p.text-h3 {{ walletStore.wallet.available }}
div
q-input(readonly standout label="Паевый счёт" v-model="walletStore.wallet.available")
//- span.text-grey Паевый счёт
//- p.text-h3 {{ walletStore.wallet.available }}
q-input(readonly standout label="Членский счёт" v-model="walletStore.wallet.blocked")
div.q-mt-md.text-right
span.text-grey Членский счёт
p.text-h3 {{ walletStore.wallet.blocked }}
</template>
@@ -5,7 +5,7 @@ const walletStore = useWalletStore()
<template lang="pug">
div.q-pa-md
q-list(v-if="walletStore.program_wallets.length > 0")
q-list
q-item(v-for="program_wallet of walletStore.program_wallets" :key="program_wallet.id" v-ripple clickable)
q-item-section
q-item-label {{ program_wallet.program_details.title }}
+2
View File
@@ -20,5 +20,7 @@ declare module 'vue-router' {
// Расширяем интерфейс RouteMeta, добавляя новые свойства
interface RouteMeta {
roles?: string[];
// title: string
// icon: string
}
}
@@ -20,7 +20,7 @@ async function createUser(data: ICreateUser): Promise<ICreatedUser> {
async function createInitialPayment(
data: ICreateInitialPayment
): Promise<ICreatedPayment> {
const response = await sendPOST('/v1/orders/initial', data);
const response = await sendPOST('/v1/payments/initial', data);
return response;
}
@@ -38,8 +38,10 @@ export function useAddPaymentMethod() {
username: params.username,
})
params.method_id = store.methods.length + 1
params.method_id = (store.methods.sort((a, b) => b.method_id - a.method_id)[0]?.method_id || 0) + 1
console.log(store.methods, store.methods.length, params.method_id)
await sendPOST(`/v1/payments/methods/${params.username}/add`, params)
await store.update({
@@ -0,0 +1 @@
export * from './ui'
@@ -0,0 +1,15 @@
<template lang="pug">
PersonalCard(:username="username")
</template>
<script lang="ts" setup>
import { PersonalCard } from 'src/widgets/Wallet/PersonalCard/ui'
import { computed } from 'vue';
import { useCurrentUserStore } from 'src/entities/User';
const currentUser = useCurrentUserStore()
const username = computed(() => currentUser.username)
</script>
@@ -0,0 +1 @@
export {default as UserIdentityPage} from './IdentityPage.vue'
@@ -0,0 +1 @@
export * from './ui'
@@ -0,0 +1,15 @@
<template lang="pug">
PaymentMethodsCard(:username="username")
</template>
<script lang="ts" setup>
import { PaymentMethodsCard } from 'src/widgets/Wallet/PaymentMethods';
import { computed } from 'vue';
import { useCurrentUserStore } from 'src/entities/User';
const currentUser = useCurrentUserStore()
const username = computed(() => currentUser.username)
</script>
@@ -0,0 +1 @@
export {default as UserPaymentMethodsPage} from './PaymentMethods.vue'
@@ -0,0 +1 @@
export * from './ui'
@@ -0,0 +1,14 @@
<template lang="pug">
WalletCard(:username="username")
</template>
<script lang="ts" setup>
import { WalletCard } from 'src/widgets/Wallet/WalletCard'
import { computed } from 'vue';
import { useCurrentUserStore } from 'src/entities/User';
const currentUser = useCurrentUserStore()
const username = computed(() => currentUser.username)
</script>
@@ -0,0 +1 @@
export {default as UserWalletPage} from './WalletPage.vue'
@@ -1,6 +1,6 @@
<template lang="pug">
div
q-tabs( v-model="tab" dense switch-indicator inline-label outside-arrows mobile-arrows align="justify" active-bg-color="teal" active-color="white" indicator-color="secondary" style="border-bottom: 1px solid teal;")
q-tabs( v-model="tab" dense switch-indicator inline-label outside-arrows mobile-arrows align="justify" active-bg-color="teal" active-color="white" indicator-color="secondary" style="border-bottom: 1px solid teal;")
q-tab(name="Удостоверение" label="Удостоверение")
q-tab(name="Кошелёк" label="Кошелёк")
q-tab(name="Реквизиты" label="Реквизиты")
@@ -6,7 +6,6 @@ q-layout(view="hHh LpR fFf")
q-btn(stretch flat class="btn-title" :dense="isMobile" @click="goToIndex").q-ml-sm
//- img(:src="HeaderLogo" alt="" style="height: 50px;").q-pa-sm
//- q-icon(name="far fa-circle").q-pa-sm
p {{ COOP_SHORT_NAME }}
q-btn(stretch flat @click="toogleDark")
@@ -20,27 +19,23 @@ q-layout(view="hHh LpR fFf")
p.q-pr-sm вход
i.fa-solid.fa-right-to-bracket
q-drawer(v-if="loggedIn" v-model="leftDrawerOpen" :mini="isMini" show-if-above side="left" persistent :mini-width="71" :width="71" class="drawer-left")
Menu(:mini="isMini")
//скрывающееся мобильное меню
q-drawer(v-if="loggedIn && isMobile" v-model="rightDrawerOpen" behavior="mobile" side="right" persistent :mini-width="71" :width="71" class="drawer-right")
Menu(:mini="false")
q-header(v-if="!isMobile && loggedIn" style="border-bottom: 1px solid #00800038 !important; " :style="{ 'background': $q.dark.isActive ? 'black' : 'white' }" :class="headerClass").header
Menu(style="border-bottom: 1px solid #00800038 !important; ")
SecondLevelMenu
//футер контактов
q-footer(v-if="!loggedIn" :class="headerClass")
ContactsFooter(:text="footerText")
q-footer(v-if="loggedIn && isMobile" style="border-top: 1px solid #00800038 !important; " :class="headerClass")
SecondLevelMenu
Menu(style="border-top: 1px solid #00800038 !important; " )
//футер мобильного меню
q-footer(v-if="loggedIn && isMobile" :class="footerClass" style="height: 55px; border-top: 1px solid #00800038 !important; " :style="{ 'background': $q.dark.isActive ? 'black' : 'white' }")
mobileMenu(@toogle-more="toggleRightDrawer")
//контейнер всех страниц
//контейнер
q-page-container
q-page(class="page" )
router-view(v-slot="{ Component }")
component(:is="Component" )
q-page
router-view
</template>
@@ -51,23 +46,28 @@ import { useRouter, useRoute } from 'vue-router'
import { useQuasar, Cookies, LocalStorage } from 'quasar'
import { useWindowSize } from 'vue-window-size'
import config from 'src/app/config'
const router = useRouter()
const route = useRoute()
// import HeaderLogo from '~/assets/logo-white.png?url'
import Menu from 'src/components/menu/drawerMenu.vue'
import mobileMenu from 'src/components/menu/footerMobileMenu.vue'
import { COOPNAME, COOP_SHORT_NAME } from 'src/shared/config'
import { useCurrentUserStore } from 'src/entities/User'
import { useSessionStore } from 'src/entities/Session'
const session = useSessionStore()
import { ContactsFooter } from 'src/shared/ui/Footer'
import { SecondLevelMenu } from 'src/entities/Desktop'
const $q = useQuasar()
const isDark = computed(() => $q.dark.isActive)
const headerClass = computed(() => (isDark.value ? 'text-white bg-dark' : 'text-black bg-light'))
const footerClass = computed(() => (isDark.value ? 'text-white' : 'text-black'))
import { useCooperativeStore } from 'src/entities/Cooperative';
const cooperativeStore = useCooperativeStore()
cooperativeStore.loadContacts()
@@ -82,29 +82,14 @@ defineExpose({
$q,
})
const router = useRouter()
const route = useRoute()
const { width } = useWindowSize()
const leftDrawerOpen = ref<boolean>(false)
const rightDrawerOpen = ref<boolean>(false)
// const toggleLeftDrawer = () => {
// leftDrawerOpen.value = !leftDrawerOpen.value
// }
const toggleRightDrawer = () => {
rightDrawerOpen.value = !rightDrawerOpen.value
}
const showRegisterButton = computed(() => {
if (!loggedIn.value) {
if (config.registrator.showRegisterButton) return true
else return false
// if (isIndexRoute.value) return config.registrator.showInIndexHeader
// else return config.registrator.showInOtherHeader
} else return false
})
@@ -122,10 +107,6 @@ if (isMobile.value == true) {
leftDrawerOpen.value = true
}
const isMini = computed(() => {
return !rightDrawerOpen.value && !rightDrawerOpen.value && !isMobile.value
})
const loggedIn = computed(() => {
return useCurrentUserStore().isRegistrationComplete && session.isAuth
})
@@ -136,6 +117,7 @@ watch(isMobile, (newValue) => {
})
watch(route, () => {
console.log('route', route)
checkAuth()
if (isMobile.value)
leftDrawerOpen.value = false
@@ -1,15 +1,11 @@
<template lang='pug'>
div
q-step(:name='3', title='Получите приватный ключ для цифровой подписи', :done='step > 3')
q-step(:name='3', title='Получите приватный ключ и надежно сохраните его для цифровой подписи', :done='step > 3')
div
p.full-width Надёжно сохраните идентификатор аккаунта и приватный ключ.
p.full-width Приватный ключ используется для входа в систему и подписи документов. Мы рекомендуем сохранить его в менеджере паролей, таком как
a(href="https://bitwarden.com").q-ml-xs Bitwarden
| .
q-input.q-mt-lg(
v-if='account.username',
v-model='account.username',
label='Идентификатор аккаунта',
:readonly='true'
)
q-input.q-mt-lg(
v-if='account.private_key',
@@ -52,7 +48,7 @@ const step = computed(() => store.step)
const userData = computed(() => store.userData)
const copyMnemonic = () => {
const toCopy = `Имя пользователя: ${account.value.username} \nПриватный ключ: ${account.value.private_key}`
const toCopy = `Приватный ключ: ${account.value.private_key}`
copyToClipboard(toCopy)
.then(() => {
@@ -19,7 +19,7 @@ div
WaitingRegistration(v-model:data='store.userData', v-model:step='store.step')
Welcome(v-model:data='store.userData', v-model:step='store.step')
q-btn(@click="logout" size="sm" flat)
q-btn(@click="out" size="sm" flat)
q-icon(name="logout")
span.q-ml-sm начать с начала
</template>
@@ -54,7 +54,7 @@ onMounted(() => {
})
const logout = async () => {
const out = async () => {
const { logout } = await useLogoutUser()
await logout()
clearLocalStorage()
@@ -85,7 +85,6 @@ onBeforeUnmount(() => {
watch(() => currentUser.participantAccount, (newValue) => {
if (newValue) {
console.log('on watch: ', currentUser.participantAccount)
store.step = 8
clearLocalStorage()
}
@@ -18,15 +18,10 @@ import { useCurrentUserStore } from 'src/entities/User';
import { COOPNAME } from 'src/shared/config';
import { Loader } from 'src/shared/ui/Loader';
const props = defineProps({
step: {
type: Number,
required: true
}
})
const currentStep = 7
const step = computed(() => props.step)
const step = computed(() => store.step)
const interval = ref()
watch(step, (newValue) => {
@@ -52,9 +47,7 @@ onBeforeUnmount(() => {
})
const update = () => {
console.log('pn start upate')
if (store.account.username && !participantAccount.value) {
console.log('on update')
currentUser.loadProfile(store.account.username, COOPNAME)
} else {
clearInterval(interval.value)
@@ -62,8 +55,7 @@ const update = () => {
}
watch(() => participantAccount, (newValue) => {
if (newValue){
console.log('on wating move')
if (newValue) {
store.step++
}
@@ -0,0 +1,7 @@
<template lang="pug">
div
</template>
<script lang="ts" setup>
</script>
@@ -0,0 +1 @@
export {default as Commutator} from './Commutator.vue'
@@ -10,6 +10,7 @@ import { ref, watch } from 'vue';
const coop = useCooperativeStore()
coop.loadPublicCooperativeData(COOPNAME)
coop.loadPrivateCooperativeData()
const localCoop = ref({
initial: 0,
@@ -24,6 +24,8 @@ import { computed } from 'vue';
const cooperative = useCooperativeStore()
cooperative.loadContacts()
cooperative.loadPrivateCooperativeData()
const details = computed(() => cooperative.privateCooperativeData)
const chairman = computed(() => `${details.value?.chairman?.last_name} ${details.value?.chairman?.first_name} ${details.value?.chairman?.middle_name}`)
@@ -3,8 +3,8 @@ q-card(flat bordered).q-pa-md
AddPaymentMethodButton(:username="username")
q-list.full-width.q-mt-lg
q-item(v-for="method in wallet.methods" :key="method.method_id").q-mt-md.full-width
q-card(flat).full-width.row.justify-center
div(v-if="method.method_type ==='sbp' && isSBPData(method.data)").col-md-10.col-xs-12
q-card(flat).full-width
div(v-if="method.method_type ==='sbp' && isSBPData(method.data)")
div.flex.justify-between
q-badge
@@ -13,7 +13,7 @@ q-card(flat bordered).q-pa-md
DeletePaymentButton(:size="'xs'" :username="username" :method_id="method.method_id")
q-input(v-model="method.data.phone" label="Номер телефона" filled readonly)
div(v-if="method.method_type ==='bank_transfer' && isBankTransferData(method.data)").col-md-10.col-xs-12
div(v-if="method.method_type ==='bank_transfer' && isBankTransferData(method.data)")
div.flex.justify-between
q-badge
span {{ method.method_id }}
@@ -8,57 +8,23 @@ q-card(v-if="currentUser?.username" flat bordered).q-pa-md.digital-certificate
AutoAvatar(style="width: 125px;" :username="currentUser.username").q-pa-sm.q-pt-lg
div.col-md-8.col-xs-12
q-list( dense )
q-item
q-item-section
q-item-label(caption) Тип
q-item-section(side)
q-badge(v-if="userType === 'individual'") физическое лицо
q-badge(v-if="userType === 'entrepreneur'") индивидуальный предприниматель
q-badge(v-if="userType === 'organization'") юридическое лицо
div().text-center
q-badge(v-if="userType === 'individual'").text-center физическое лицо
q-badge(v-if="userType === 'entrepreneur'").text-center индивидуальный предприниматель
q-badge(v-if="userType === 'organization'").text-center юридическое лицо
q-item
q-item-section
q-item-label(caption) Идентификатор
q-item-section(side)
q-item-label(lines=2) {{ currentUser.username }}
q-input(standout dense label="Идентификатор" v-model="currentUser.username" readonly)
q-item
q-item-section
q-item-label(v-if="userType !== 'organization'" caption) ФИО
q-item-label(v-else caption) Наименование
q-item-section(side)
template(v-if="userType === 'individual'")
q-item-label(lines=2 caption) {{ individualProfile?.last_name }} {{ individualProfile?.first_name }} {{ individualProfile?.middle_name }}
template(v-else-if="userType === 'entrepreneur'")
q-item-label(lines=2 caption) {{ entrepreneurProfile?.last_name }} {{ entrepreneurProfile?.first_name }} {{ entrepreneurProfile?.middle_name }}
template(v-else)
q-item-label(caption) {{ organizationProfile?.short_name }}
q-input(standout dense label="Пайщик" readonly v-model="displayName")
q-item(v-if="userType === 'individual'")
q-item-section
q-item-label(caption) Дата рождения
q-item-section(side) {{ individualProfile?.birthdate }}
q-input(v-if="userType === 'individual' && individualProfile" standout dense label="Дата рождения" readonly v-model="individualProfile.birthdate")
q-item(v-if="userType === 'organization'")
q-item-section
q-item-label(caption) ИНН / ОГРН
q-item-section(side) {{ organizationProfile?.details.inn }} / {{ organizationProfile?.details.ogrn }}
q-input(v-if="userType === 'organization' && organizationProfile" standout dense label="ИНН / ОГРН" readonly v-model="inn_ogrn")
q-item
q-item-section
q-item-label(caption) Адрес регистрации
q-item-section(side)
q-item-label(lines=2) {{ userProfile?.full_address }}
q-input(v-if="userProfile" standout dense label="Телефон" readonly v-model="userProfile.phone")
q-item
q-item-section
q-item-label(caption) Телефон
q-item-section(side) {{ userProfile?.phone }}
q-input(v-if="userProfile" standout dense label="Почта" readonly v-model="userProfile.email")
q-item
q-item-section
q-item-label(caption) Почта
q-item-section(side) {{ userProfile?.email }}
</template>
<script lang="ts" setup>
@@ -97,4 +63,26 @@ const userProfile = computed(() => {
}
return organizationProfile?.value
})
const displayName = computed(() => {
if (userType.value === 'individual') {
return `${individualProfile.value?.last_name} ${individualProfile.value?.first_name} ${individualProfile.value?.middle_name}`
} else if (userType.value === 'entrepreneur') {
return `${entrepreneurProfile.value?.last_name} ${entrepreneurProfile.value?.first_name} ${entrepreneurProfile.value?.middle_name}`
} else {
return organizationProfile.value?.short_name
}
})
const inn_ogrn = computed(() => {
if (organizationProfile.value)
return `${organizationProfile.value.details.inn} / ${organizationProfile.value.details.ogrn}`
else return ''
})
</script>
<style>
.digital-certificate {
padding: 50px !important;
}
</style>
@@ -1,13 +1,16 @@
<template lang="pug">
q-card(flat bordered).q-pa-md
//- p.text-bold.full-width.text-sm.text-center КОШЕЛЁК
WalletBalance
div.flex.justify-center.q-gutter-sm.q-pa-md
DepositButton
WithdrawButton
div.row
div.col-md-6.col-xs-12.q-gutter-sm
div.flex.q-pa-sm
DepositButton.q-ma-sm
WithdrawButton.q-ma-sm
div.col-md-6.col-xs-12.q-gutter-sm
WalletBalance
WalletProgramsList
</template>
<script lang="ts" setup>
import { WalletBalance } from 'src/entities/Wallet/ui'
import { useWalletStore } from 'src/entities/Wallet/model/stores'