Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • d.malygin/shelfNote
1 result
Show changes
Commits on Source (4)
Showing
with 5846 additions and 120 deletions
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {};
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
Avatar: typeof import('primevue/avatar')['default']
Button: typeof import('primevue/button')['default']
CreateEntityMenu: typeof import('./src/components/CreateEntityMenu.vue')['default']
Divider: typeof import('primevue/divider')['default']
Drawer: typeof import('primevue/drawer')['default']
LogoAndLabel: typeof import('./src/components/LogoAndLabel.vue')['default']
Popover: typeof import('primevue/popover')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
ScrollPanel: typeof import('primevue/scrollpanel')['default']
SpeedDial: typeof import('primevue/speeddial')['default']
Splitter: typeof import('primevue/splitter')['default']
SplitterPanel: typeof import('primevue/splitterpanel')['default']
Textarea: typeof import('primevue/textarea')['default']
TextItem: typeof import('./src/components/entities/TextItem.vue')['default']
Tree: typeof import('primevue/tree')['default']
UserInfoHeaderWithSettings: typeof import('./src/components/UserInfoHeaderWithSettings.vue')['default']
}
}
...@@ -4,10 +4,11 @@ ...@@ -4,10 +4,11 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title> <link href="./src/output.css" rel="stylesheet">
<title>Motion</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module" src="./src/main.ts"></script> <script type="module" src="./src/main.ts"></script>
</body> </body>
</html> </html>
This diff is collapsed.
...@@ -13,16 +13,24 @@ ...@@ -13,16 +13,24 @@
"format": "prettier --write src/" "format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"@primevue/themes": "^4.0.4",
"@vueuse/core": "^10.11.0",
"@vueuse/integrations": "^10.11.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"primeicons": "^7.0.0",
"primevue": "^4.0.4", "primevue": "^4.0.4",
"tailwindcss": "^3.4.7", "tailwindcss": "^3.4.7",
"universal-cookie": "^7",
"uuid": "^10.0.0",
"vue": "^3.4.29", "vue": "^3.4.29",
"vue-router": "^4.3.3" "vue-router": "^4.3.3"
}, },
"devDependencies": { "devDependencies": {
"@primevue/auto-import-resolver": "^4.0.4",
"@rushstack/eslint-patch": "^1.8.0", "@rushstack/eslint-patch": "^1.8.0",
"@tsconfig/node20": "^20.1.4", "@tsconfig/node20": "^20.1.4",
"@types/node": "^20.14.5", "@types/node": "^20.14.5",
"@types/uuid": "^10.0.0",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0", "@vue/eslint-config-typescript": "^13.0.0",
...@@ -33,6 +41,7 @@ ...@@ -33,6 +41,7 @@
"prettier": "^3.2.5", "prettier": "^3.2.5",
"typescript": "~5.4.0", "typescript": "~5.4.0",
"unplugin-auto-import": "^0.18.2", "unplugin-auto-import": "^0.18.2",
"unplugin-vue-components": "^0.27.3",
"vite": "^5.3.1", "vite": "^5.3.1",
"vue-tsc": "^2.0.21" "vue-tsc": "^2.0.21"
} }
......
public/favicon.ico

264 KiB | W: 256px | H: 256px

public/favicon.ico

422 KiB | W: 256px | H: 256px

public/favicon.ico
public/favicon.ico
public/favicon.ico
public/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
<script setup lang="ts"> <script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'; import 'primeicons/primeicons.css';
import BaseMenu from '@/modules/BaseMenu.vue'; import BaseMenu from '@/modules/BaseMenu.vue';
const baseMenu = ref(); const visible = ref<boolean>(false);
const toggleMenu = (event) => {
baseMenu.value.toggle(event);
};
</script> </script>
<template> <template>
<header> <router-view />
<div class="wrapper"> <div class="absolute top-0 left-0">
<h1>ggggggggggggggggggggggggggggggggggggggggggggggg</h1> <Button
<nav> @click.prevent="visible = !visible"
<RouterLink to="/">Home</RouterLink> label="Menu"
<RouterLink to="/about">About</RouterLink> iconPos="top"
</nav> icon="pi pi-bars"
</div> severity="secondary"
</header> />
<Button @click="toggleMenu">Menu</Button> </div>
<BaseMenu ref="baseMenu" /> <Drawer v-model:visible="visible">
<RouterView /> <template #container="{ closeCallback }">
<BaseMenu @closeCallback="closeCallback" />
</template>
</Drawer>
</template> </template>
<style scoped></style> <style scoped></style>
This diff is collapsed.
body {
min-height: 100vh;
}
#app {
min-height: 100vh;
display: flex;
flex-flow: column;
}
#app > main {
flex: 1 1 auto;
}
/* Reset and base styles */
* {
padding: 0;
margin: 0;
border: none;
}
*, *,
*::before, *::before,
*::after { *::after {
box-sizing: border-box; box-sizing: border-box;
margin: 0;
font-weight: normal;
} }
body { /* Links */
min-height: 100vh;
} a, a:link, a:visited {
\ No newline at end of file text-decoration: none;
}
a:hover {
text-decoration: none;
}
/* Common */
aside, nav, footer, header, section, main {
display: block;
}
h1, h2, h3, h4, h5, h6, p {
font-size: inherit;
font-weight: inherit;
}
ul, ul li {
list-style: none;
}
img {
vertical-align: top;
}
img, svg {
max-width: 100%;
height: auto;
}
address {
font-style: normal;
}
/* Form */
input, textarea, button, select {
font-family: inherit;
font-size: inherit;
color: inherit;
background-color: transparent;
}
input::-ms-clear {
display: none;
}
button, input[type="submit"] {
display: inline-block;
box-shadow: none;
background-color: transparent;
background: none;
cursor: pointer;
}
input:focus, input:active,
button:focus, button:active {
outline: none;
}
button::-moz-focus-inner {
padding: 0;
border: 0;
}
label {
cursor: pointer;
}
legend {
display: block;
}
<script setup lang="ts"></script>
<template>
<span class="inline-flex items-center gap-2"
><img src="@/assets/Motion.svg" alt="Motion logo" class="bg-white size-12" />
<span class="font-semibold text-2xl text-primary">Motion</span></span
>
</template>
<style scoped></style>
<script setup lang="ts">
import { useAuthorizationStore } from '@/stores/authorization';
const authorizationStore = useAuthorizationStore();
const userNickName = computed(() => authorizationStore.userNickName);
</script>
<template>
<div>
<Avatar label="D" class="mr-2" size="large" shape="circle" style="background-color: #60a5fa" />
<span class="text-xl">@{{ userNickName }}</span>
</div>
<a
href="/settings"
class="pi pi-cog ml-auto p-2 -m-2 hover:cursor-pointer"
style="font-size: 2rem"
></a>
</template>
<style scoped></style>
import { useInterfaceStore } from '@/stores/interface';
import type { IEntity } from '@/interfaces/environment';
export async function uploadFile($event: Event) {
const target = $event.target as HTMLInputElement;
if (target && target.files && target.files[0]) {
const file = target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.addEventListener('load', () => {
const url = reader.result;
const interfaceStore = useInterfaceStore();
interfaceStore.changeHomeBackgroundUrl(url);
localStorage.setItem('homeBackgroundUrl', url);
});
}
}
export function setDefaultHomeBackground() {
const interfaceStore = useInterfaceStore();
interfaceStore.changeHomeBackgroundUrl(
'https://wallpapers.com/images/featured/minimalist-7xpryajznty61ra3.jpg'
);
localStorage.removeItem('homeBackgroundUrl');
}
@tailwind base;
@tailwind components;
@tailwind utilities;
\ No newline at end of file
...@@ -2,7 +2,10 @@ import type { IImage, TThemes } from '@/interfaces/environment'; ...@@ -2,7 +2,10 @@ import type { IImage, TThemes } from '@/interfaces/environment';
export interface IUserData { export interface IUserData {
uuid: string; uuid: string;
fullName: string; nickName: string;
firstName: string;
lastName: string;
middleName: string;
email: string; email: string;
phoneNumber: string; phoneNumber: string;
settings: IUserSettings; settings: IUserSettings;
......
...@@ -5,10 +5,17 @@ import { createPinia } from 'pinia'; ...@@ -5,10 +5,17 @@ import { createPinia } from 'pinia';
import PrimeVue from 'primevue/config'; import PrimeVue from 'primevue/config';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
import Aura from '@primevue/themes/aura';
const app = createApp(App); const app = createApp(App);
app.use(createPinia()); app
app.use(router); .use(PrimeVue, {
app.use(PrimeVue); theme: {
app.mount('#app'); preset: Aura,
options: {}
}
})
.use(createPinia())
.use(router)
.mount('#app');
<script setup lang="ts"></script> <script setup lang="ts">
import LogoAndLabel from '@/components/LogoAndLabel.vue';
import { useDataStore } from '@/stores/data';
import UserInfoHeaderWithSettings from '@/components/UserInfoHeaderWithSettings.vue';
const route = useRoute();
const emit = defineEmits(['closeCallback']);
const dataStore = useDataStore();
const sheets = ref();
const expandAll = () => {
for (let sheet of sheets.value) {
expandSheet(sheet);
}
expandedKeys.value = { ...expandedKeys.value };
};
const expandSheet = (sheet) => {
if (sheet.children && sheet.children.length) {
expandedKeys.value[sheet.key] = true;
for (let child of sheet.children) {
expandSheet(child);
}
}
};
onMounted(() => {
sheets.value = dataStore.sheets;
expandAll();
});
const expandedKeys = ref({});
</script>
<template> <template>
<Popover> <div class="flex flex-col h-full p-4">
<div class="h-full"> <section class="flex justify-between items-center mb-6">
<ul> <LogoAndLabel />
<li>What I want</li> <Button
<li>My targets</li> severity="contrast"
<li>My love</li> @click="emit('closeCallback')"
<li>My owns</li> icon="pi pi-times"
<li>My clowns</li> rounded
</ul> outlined
</div> ></Button>
</Popover> </section>
<section class="flex items-center justify-between mb-6">
<UserInfoHeaderWithSettings />
</section>
<Divider />
<nav>
<h3 class="text-xl">Menu</h3>
<div class="ml-[58px] mt-4 -mb-2 select-none font-bold">
<a v-if="route.path !== '/'" href="/"
><i class="pi pi-home text-gray-400 pr-2"></i>Главное меню</a
>
<span v-else><i class="pi pi-home text-gray-400 pr-2"></i>Главное меню</span>
</div>
<Tree
:value="sheets"
v-model:expandedKeys="expandedKeys"
pt:root:class="pl-0"
pt:sheetLabel:class="text-white"
>
<template #url="slotProps">
<a
:href="slotProps.node.data"
:class="[
'block',
{
'bg-sky-900 p-2 ml-0 -m-2 rounded-md': route.path === slotProps.node.data
}
]"
>{{ slotProps.node.label }}</a
>
</template>
</Tree>
</nav>
</div>
</template> </template>
<style scoped></style> <style scoped></style>
This diff is collapsed.
<script setup lang="ts"></script> <script setup lang="ts">
import { useElementSize } from '@vueuse/core';
import EntityItem from '@/modules/EntityItem.vue';
import CreateEntityMenu from '@/components/CreateEntityMenu.vue';
import { setDefaultHomeBackground, uploadFile } from '@/helpers ';
import { useInterfaceStore } from '@/stores/interface';
import type { IEntity } from '@/interfaces/environment';
<template></template> const backgroundImage = ref();
const { height: backgroundImageHeight } = useElementSize(backgroundImage);
const entitiesContainer = ref();
const { height: entitiesHeight } = useElementSize(entitiesContainer);
<style scoped></style> const entities = ref([]);
const addEntity = (newEntity: IEntity) => {
entities.value.push(newEntity);
};
const interfaceStore = useInterfaceStore();
const backgroundUrl = computed<string>(() => interfaceStore.homeBackgroundUrl);
</script>
<template>
<header>
<h1 class="text-center text-4xl py-4">Home page</h1>
</header>
<main class="flex flex-col">
<Splitter
:style="`height: calc(${backgroundImageHeight - 3}px + ${entitiesHeight}px + 150px);`"
layout="vertical"
stateKey="homeSplitter"
stateStorage="local"
>
<SplitterPanel
ref="splitterBackground"
:pt:root:style="`position: relative; background-image: url(${backgroundUrl}); background-size: 100% auto; max-height: ${backgroundImageHeight - 3}px; min-height: 200px;`"
class="splitterPanelBackground"
>
<div
class="changeImageBlock absolute top-2 right-2 bg-black p-2 rounded-md hover:text-gray-300 transition-all cursor-pointer select-none"
>
<input
type="file"
@change="uploadFile($event)"
title="Change image"
accept="image/*"
class="w-2 pr-[135px] -mr-[135px] py-2 -my-2 pl-2 -ml-2 opacity-0 cursor-pointer"
/><span class="cursor-pointer"><i class="pi pi-image mr-2"></i>Change image</span>
</div>
<button
@click.prevent="setDefaultHomeBackground"
class="returnDefaultImageBlock absolute top-16 right-2 bg-blue-600 p-2 transition-all rounded-md border-2 border-solid border-black select-none"
>
Return default image
</button>
</SplitterPanel>
<SplitterPanel class="flex items-start justify-center"
><div ref="entitiesContainer" class="pt-6">
<p class="mb-6">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad autem cum dolores doloribus
dolorum, earum illum nam nemo nesciunt odit pariatur quam quisquam reprehenderit
sapiente ullam unde ut vel, voluptatem!
</p>
<EntityItem
v-for="entitiesItem of entities"
:entity="entitiesItem"
:key="entitiesItem.uuid"
class="mb-6"
/>
<div class="relative">
<CreateEntityMenu @addEntity="addEntity" />
</div>
</div>
</SplitterPanel>
</Splitter>
</main>
<img
ref="backgroundImage"
:src="backgroundUrl"
alt="background image"
class="absolute w-full -top-full -left-full"
/>
</template>
<style scoped>
.splitterPanelBackground > .changeImageBlock,
.splitterPanelBackground > .returnDefaultImageBlock {
opacity: 0;
}
.splitterPanelBackground:hover > .changeImageBlock,
.splitterPanelBackground:hover > .returnDefaultImageBlock {
opacity: 100;
}
</style>
...@@ -10,12 +10,12 @@ const router = createRouter({ ...@@ -10,12 +10,12 @@ const router = createRouter({
component: HomePage component: HomePage
}, },
{ {
path: '/sheet/:sheetUuid', path: '/:sheetUuid',
name: 'about', name: 'sheet',
// route level code-splitting // route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route // this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => import('../pages/SheetPage.vue') component: () => import('../pages/[uuid]/SheetPage.vue')
} }
] ]
}); });
......
...@@ -3,11 +3,12 @@ import type { IUserData } from '@/interfaces/authorization'; ...@@ -3,11 +3,12 @@ import type { IUserData } from '@/interfaces/authorization';
export const useAuthorizationStore = defineStore('authorizationStore', () => { export const useAuthorizationStore = defineStore('authorizationStore', () => {
const userUuid = ref<string>('e786de50-f33c-4ef9-9dfe-329eed32b023'); const userUuid = ref<string>('e786de50-f33c-4ef9-9dfe-329eed32b023');
const userNickName = ref<string>('malyusgun');
const userData = ref<IUserData | null>(); const userData = ref<IUserData | null>();
// const doubleCount = computed(() => count.value * 2); // const doubleCount = computed(() => count.value * 2);
// function increment() { // function increment() {
// count.value++; // count.value++;
// } // }
return { userUuid, userData }; return { userUuid, userNickName, userData };
}); });
This diff is collapsed.