initial
This commit is contained in:
51
apps/client/components/page/block.vue
Normal file
51
apps/client/components/page/block.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="page-block">
|
||||
<div class="page-block__header">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center" style="gap: 16px">
|
||||
<h3 v-if="title">
|
||||
{{ title }}
|
||||
</h3>
|
||||
|
||||
<slot name="badge" />
|
||||
</div>
|
||||
<span v-if="subTitle" class="page-block__subtitle">{{ subTitle }}</span>
|
||||
</div>
|
||||
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: { type: String },
|
||||
subTitle: { type: String },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--page-block-gap, 8px);
|
||||
|
||||
border-radius: 12px;
|
||||
padding: var(--page-block-padding, 16px);
|
||||
background-color: $clr-white;
|
||||
|
||||
&__header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__subtitle{
|
||||
@include txt-i-m;
|
||||
margin-top: 4px;
|
||||
color: $clr-grey-500;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
78
apps/client/components/page/footer-info-block.vue
Normal file
78
apps/client/components/page/footer-info-block.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div class="footer-info-block">
|
||||
<div class="footer-info-block__left">
|
||||
<UiIconAskForDiscountFilled class="footer-info-block__icon" />
|
||||
<div>
|
||||
<h3 class="footer-info-block__title">
|
||||
{{ title }}
|
||||
</h3>
|
||||
<p class="footer-info-block__text">
|
||||
{{ text }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-info-block__right">
|
||||
<UiButton
|
||||
color="secondary"
|
||||
right-icon="s-chevron-right"
|
||||
>
|
||||
{{ action }}
|
||||
</UiButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: { type: String, required: true },
|
||||
text: { type: String, required: true },
|
||||
action: { type: String, required: true },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.footer-info-block {
|
||||
display: flex;
|
||||
|
||||
&__title {
|
||||
color: $clr-grey-600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
color: $clr-grey-500;
|
||||
width: 512px;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
color: $clr-market-500 !important;
|
||||
margin-right: 32px;
|
||||
padding: 9px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
&__left {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
border-bottom-left-radius: 12px;
|
||||
border-top-left-radius: 12px;
|
||||
|
||||
background-color: $clr-grey-200;
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
&__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
border-bottom-right-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
background-color: $clr-grey-300;
|
||||
|
||||
width: 286px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
90
apps/client/components/page/header.vue
Normal file
90
apps/client/components/page/header.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<header class="page-header">
|
||||
<div class="page-header__title">
|
||||
<UiButton
|
||||
v-if="withBackButton"
|
||||
icon="arrow-left"
|
||||
color="secondary"
|
||||
class="mr-24"
|
||||
href="/projects"
|
||||
type="outlined"
|
||||
/>
|
||||
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<div
|
||||
v-if="$slots.default"
|
||||
class="page-header__default"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-header__right">
|
||||
<slot name="right">
|
||||
<div class="d-flex align-items-center" style="gap: 24px;">
|
||||
<NotificationsDropdown />
|
||||
<ProfileDropdown />
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
withBackButton: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const notify = useNotify()
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use 'sass:color';
|
||||
|
||||
.page-header {
|
||||
position: sticky;
|
||||
backdrop-filter: blur(4px);
|
||||
background-size: 4px 4px;
|
||||
background-image: radial-gradient(
|
||||
color.change($clr-grey-100, $alpha: 0.7) 2px,
|
||||
$clr-cyan-200
|
||||
);
|
||||
border-bottom: 1px solid #f4f6ff;
|
||||
margin-inline: -16px;
|
||||
padding-inline: 16px;
|
||||
top: 0;
|
||||
z-index: 6000;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
//margin-bottom: 32px;
|
||||
padding-block: 32px;
|
||||
|
||||
&__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
&__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
97
apps/client/components/page/info-block.vue
Normal file
97
apps/client/components/page/info-block.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="info-block">
|
||||
<div class="d-flex justify-content-between mb-16">
|
||||
<p class="info-block__title">
|
||||
{{ title }}
|
||||
</p>
|
||||
<UiBadge v-if="badge" type="marketing">
|
||||
{{ badge }}
|
||||
</UiBadge>
|
||||
</div>
|
||||
|
||||
<slot name="info" />
|
||||
|
||||
<span class="info-block__text">{{ text }}</span>
|
||||
|
||||
<UiButton
|
||||
class="info-block__action"
|
||||
type="outlined"
|
||||
:href="link"
|
||||
right-icon="s-chevron-right"
|
||||
size="small"
|
||||
>
|
||||
{{ action }}
|
||||
</UiButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
badge: {
|
||||
type: String,
|
||||
},
|
||||
action: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
link: {
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.info-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 270px;
|
||||
min-height: 179px;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
|
||||
background-color: $clr-grey-100;
|
||||
|
||||
&__title {
|
||||
@include txt-m-sb;
|
||||
}
|
||||
|
||||
&__text {
|
||||
@include txt-s;
|
||||
margin-bottom: 16px;
|
||||
color: $clr-grey-500;
|
||||
}
|
||||
|
||||
&__action {
|
||||
margin-top: auto;
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.info-block-addInfo {
|
||||
@include txt-s;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&__title {
|
||||
margin-bottom: 4px;
|
||||
color: $clr-grey-500;
|
||||
}
|
||||
|
||||
&__sum {
|
||||
@include txt-m-sb;
|
||||
}
|
||||
|
||||
&__text {
|
||||
@include txt-r;
|
||||
color: $clr-grey-400;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
32
apps/client/components/page/toolbar.vue
Normal file
32
apps/client/components/page/toolbar.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="page-toolbar">
|
||||
<slot name="prefix" />
|
||||
|
||||
<UiSearch
|
||||
class="flex-1"
|
||||
size="large"
|
||||
:label="searchLabel"
|
||||
:model-value="search"
|
||||
@update:model-value="$emit('update:search', $event)"
|
||||
/>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
searchLabel: { type: String, required: true },
|
||||
search: { type: String },
|
||||
})
|
||||
|
||||
defineEmits(['update:search'])
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page-toolbar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user