add player

This commit is contained in:
Stepan Fedyanin 2024-06-14 17:34:20 +05:00
parent f433380466
commit 9d8d874607
26 changed files with 1229 additions and 907 deletions

126
client/package-lock.json generated
View File

@ -11,7 +11,6 @@
"@formkit/i18n": "^1.6.3", "@formkit/i18n": "^1.6.3",
"@formkit/vue": "^1.6.3", "@formkit/vue": "^1.6.3",
"@quasar/extras": "^1.16.4", "@quasar/extras": "^1.16.4",
"@vueuse/components": "^10.10.0",
"axios": "^1.2.1", "axios": "^1.2.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"esm": "^3.2.25", "esm": "^3.2.25",
@ -22,6 +21,7 @@
"scrolltrigger": "^1.0.1", "scrolltrigger": "^1.0.1",
"swiper": "^11.1.3", "swiper": "^11.1.3",
"vue": "^3.3.13", "vue": "^3.3.13",
"vue-content-loader": "^2.0.1",
"vue-final-modal": "^4.5.4", "vue-final-modal": "^4.5.4",
"vue-router": "^4.0.0", "vue-router": "^4.0.0",
"vuex": "^4.0.1", "vuex": "^4.0.1",
@ -3990,74 +3990,6 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
}, },
"node_modules/@vueuse/components": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.10.0.tgz",
"integrity": "sha512-HiA10NQ9HJAGnju+8ZK4TyA8LIc0a6BnJmVWDa/k+TRhaYCVacSDU04k0BQ2otV+gghUDdwu98upf6TDRXpoeg==",
"dependencies": {
"@vueuse/core": "10.10.0",
"@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7"
}
},
"node_modules/@vueuse/components/node_modules/@vueuse/core": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.10.0.tgz",
"integrity": "sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.10.0",
"@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/components/node_modules/@vueuse/metadata": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.10.0.tgz",
"integrity": "sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/components/node_modules/@vueuse/shared": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.10.0.tgz",
"integrity": "sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==",
"dependencies": {
"vue-demi": ">=0.14.7"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/components/node_modules/vue-demi": {
"version": "0.14.8",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
"integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/core": { "node_modules/@vueuse/core": {
"version": "10.9.0", "version": "10.9.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
@ -15061,6 +14993,14 @@
} }
} }
}, },
"node_modules/vue-content-loader": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/vue-content-loader/-/vue-content-loader-2.0.1.tgz",
"integrity": "sha512-pkof4+q2xmzNEdhqelxtJejeP/vQUJtLle4/v2ueG+HURqM9Q/GIGC8GJ2bVVWeLfTDET51jqimwQdmxJTlu0g==",
"peerDependencies": {
"vue": "^3"
}
},
"node_modules/vue-eslint-parser": { "node_modules/vue-eslint-parser": {
"version": "9.3.2", "version": "9.3.2",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",
@ -18623,48 +18563,6 @@
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
}, },
"@vueuse/components": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.10.0.tgz",
"integrity": "sha512-HiA10NQ9HJAGnju+8ZK4TyA8LIc0a6BnJmVWDa/k+TRhaYCVacSDU04k0BQ2otV+gghUDdwu98upf6TDRXpoeg==",
"requires": {
"@vueuse/core": "10.10.0",
"@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7"
},
"dependencies": {
"@vueuse/core": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.10.0.tgz",
"integrity": "sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==",
"requires": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.10.0",
"@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7"
}
},
"@vueuse/metadata": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.10.0.tgz",
"integrity": "sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug=="
},
"@vueuse/shared": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.10.0.tgz",
"integrity": "sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==",
"requires": {
"vue-demi": ">=0.14.7"
}
},
"vue-demi": {
"version": "0.14.8",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
"integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
"requires": {}
}
}
},
"@vueuse/core": { "@vueuse/core": {
"version": "10.9.0", "version": "10.9.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
@ -26407,6 +26305,12 @@
"@vue/shared": "3.4.27" "@vue/shared": "3.4.27"
} }
}, },
"vue-content-loader": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/vue-content-loader/-/vue-content-loader-2.0.1.tgz",
"integrity": "sha512-pkof4+q2xmzNEdhqelxtJejeP/vQUJtLle4/v2ueG+HURqM9Q/GIGC8GJ2bVVWeLfTDET51jqimwQdmxJTlu0g==",
"requires": {}
},
"vue-eslint-parser": { "vue-eslint-parser": {
"version": "9.3.2", "version": "9.3.2",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",

View File

@ -29,6 +29,7 @@
"scrolltrigger": "^1.0.1", "scrolltrigger": "^1.0.1",
"swiper": "^11.1.3", "swiper": "^11.1.3",
"vue": "^3.3.13", "vue": "^3.3.13",
"vue-content-loader": "^2.0.1",
"vue-final-modal": "^4.5.4", "vue-final-modal": "^4.5.4",
"vue-router": "^4.0.0", "vue-router": "^4.0.0",
"vuex": "^4.0.1", "vuex": "^4.0.1",

View File

@ -62,7 +62,7 @@ a {
} }
html{ html{
scrollbar-color: var(--color-black) var(--color-white-opacity); scrollbar-color: var(--color-black) var(--bg-opacity);
scrollbar-gutter: stable; scrollbar-gutter: stable;
scrollbar-width: thin; scrollbar-width: thin;
} }

View File

@ -1,326 +1,336 @@
@define-mixin __p { @define-mixin __p {
position: relative;
z-index: 2;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
&.m--mb-1 {
margin-bottom: 1rem;
}
&.m--mb-2 {
margin-bottom: 2rem;
}
&.m--mb-3 {
margin-bottom: 3rem;
}
&.m--mb-4 {
margin-bottom: 4rem;
}
&.m--mb-5 {
margin-bottom: 5rem;
}
}
@define-mixin h1 {
@mixin __p;
/*margin-top: 32px;*/
margin-bottom: 1.5rem;
font-size: 100px;
line-height: 1.2;
font-weight: 500;
color: var(--color-white);
padding-bottom: 6px;
@mixin responsive-l {
font-size: 84px;
}
@mixin responsive-m {
font-size: 48px;
}
@mixin responsive-s {
font-size: 36px;
}
}
@define-mixin h2 {
@mixin __p;
margin: 2.5rem 0;
font-size: 3.375rem;
line-height: 1.3;
font-weight: 500;
color: transparent;
padding-bottom: 6px;
background-clip: text;
background-image: var(--linear-gradient);
text-transform: uppercase;
&.m--white {
color: var(--color-white);
margin: 1.5rem 0;
}
&.m--border {
&:after {
margin-top: 10px;
content: '';
display: block;
background: url("./assets/img/icon/borderLine.svg");
max-width: 260px;
width: 100%;
height: 10px;
}
}
a {
text-decoration: none;
font-weight: 500;
color: var(--color-white);
transition: color 0.5s ease;
&:hover {
color: var(--color-white);
}
}
}
@define-mixin h3 {
@mixin __p;
margin-top: 24px;
margin-bottom: 16px;
font-weight: 700;
font-size: 20px;
line-height: 1.2;
}
@define-mixin h4 {
@mixin __p;
margin-top: 16px;
margin-bottom: 8px;
font-weight: 500;
font-size: 18px;
line-height: 1.2;
}
@define-mixin p {
@mixin __p;
margin-top: 8px;
margin-bottom: 8px;
}
@define-mixin ul {
@mixin p;
list-style: none;
padding: 0;
li {
padding-left: 15px;
position: relative; position: relative;
margin-bottom: 16px; z-index: 2;
&:first-child {
/* &:before { margin-top: 0;
content: '';
position: absolute;
left: 0;
width: 15px;
height: 14px;
top: 3px;
background-size: contain;
background-position: center;
background-image: svg-load('assets/img/icons/vector.svg', fill=$color-red);
background-repeat: no-repeat;
}*/
&:before {
content: '';
position: absolute;
left: 0;
width: 5px;
height: 5px;
top: 7px;
background: var(--color-white);
border-radius: 50%;
} }
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
}
&.m--dots { &.m--mb-1 {
margin-bottom: 1rem;
}
&.m--mb-2 {
margin-bottom: 2rem;
}
&.m--mb-3 {
margin-bottom: 3rem;
}
&.m--mb-4 {
margin-bottom: 4rem;
}
&.m--mb-5 {
margin-bottom: 5rem;
}
}
@define-mixin h1 {
@mixin __p;
/*margin-top: 32px;*/
margin-bottom: 1.5rem;
font-size: 100px;
line-height: 1.2;
font-weight: 500;
color: var(--color-white);
padding-bottom: 6px;
@mixin responsive-l {
font-size: 84px;
}
@mixin responsive-m {
font-size: 48px;
}
@mixin responsive-s {
font-size: 36px;
}
}
@define-mixin h2 {
@mixin __p;
margin: 2.5rem 0;
font-size: 3.375rem;
line-height: 1.3;
font-weight: 500;
color: transparent;
padding-bottom: 6px;
background-clip: text;
background-image: var(--linear-gradient);
text-transform: uppercase;
@mixin responsive-l {
font-size:40px;
line-height: 1.1;
}
@mixin responsive-m {
font-size:32px;
}
/*@mixin responsive-s {
font-size: 36px;
}*/
&.m--white {
color: var(--color-white);
margin: 1.5rem 0;
}
&.m--border {
&:after {
margin-top: 10px;
content: '';
display: block;
background: url("./assets/img/icon/borderLine.svg");
max-width: 260px;
width: 100%;
height: 10px;
}
}
a {
text-decoration: none;
font-weight: 500;
color: var(--color-white);
transition: color 0.5s ease;
&:hover {
color: var(--color-white);
}
}
}
@define-mixin h3 {
@mixin __p;
margin-top: 24px;
margin-bottom: 16px;
font-weight: 700;
font-size: 20px;
line-height: 1.2;
}
@define-mixin h4 {
@mixin __p;
margin-top: 16px;
margin-bottom: 8px;
font-weight: 500;
font-size: 18px;
line-height: 1.2;
}
@define-mixin p {
@mixin __p;
margin-top: 8px;
margin-bottom: 8px;
}
@define-mixin ul {
@mixin p;
list-style: none;
padding: 0;
li { li {
padding-left: 1rem; padding-left: 15px;
position: relative;
margin-bottom: 16px;
&:before { /* &:before {
content: ''; content: '';
top: 0; position: absolute;
height: auto; left: 0;
width: auto; width: 15px;
background: none; height: 14px;
} top: 3px;
background-size: contain;
background-position: center;
background-image: svg-load('assets/img/icons/vector.svg', fill=$color-red);
background-repeat: no-repeat;
}*/
&:before {
content: '';
position: absolute;
left: 0;
width: 5px;
height: 5px;
top: 7px;
background: var(--color-white);
border-radius: 50%;
}
&:last-child {
margin-bottom: 0;
}
}
&.m--dots {
li {
padding-left: 1rem;
&:before {
content: '';
top: 0;
height: auto;
width: auto;
background: none;
}
}
} }
}
} }
@define-mixin ol { @define-mixin ol {
@mixin p; @mixin p;
list-style: none; list-style: none;
counter-reset: item; counter-reset: item;
li { li {
counter-increment: item; counter-increment: item;
margin-bottom: 16px; margin-bottom: 16px;
vertical-align: middle; vertical-align: middle;
&:before { &:before {
content: counter(item); content: counter(item);
padding-left: 12px; padding-left: 12px;
font-weight: 500; font-weight: 500;
font-size: 18px; font-size: 18px;
line-height: 24px; line-height: 24px;
color: var(--color-white); color: var(--color-white);
}
} }
}
} }
@define-mixin hr { @define-mixin hr {
@mixin p; @mixin p;
} }
@define-mixin a { @define-mixin a {
text-decoration: none;
font-weight: 500;
transition: all 0.5s ease;
color: var(--color-white);
position: relative;
z-index: 2;
&:hover {
color: transparent;
-webkit-background-clip: text;
background-image: var(--linear-gradient);
cursor: url("./assets/img/icon/cursor.svg"), auto;
text-decoration: none; text-decoration: none;
} font-weight: 500;
transition: all 0.5s ease;
&.m--link { color: var(--color-white);
display: flex; position: relative;
align-items: center; z-index: 2;
border-bottom: 1px solid transparent;
&::after {
margin-left: 10px;
content: '';
width: 20px;
height: 20px;
background: svg-load('./assets/img/icon/ArrowRight.svg', stroke=#FFFF) no-repeat 100%;
background-size: cover;
transition: background 0.3s ease, width 0.3s ease;
}
&:hover { &:hover {
color: var(--color-white); color: transparent;
border-bottom: 1px solid var(--color-white); -webkit-background-clip: text;
background-image: var(--linear-gradient);
cursor: url("./assets/img/icon/cursor.svg"), auto;
text-decoration: none;
} }
&:hover::after { &.m--link {
width: 40px; display: flex;
align-items: center;
border-bottom: 1px solid transparent;
&::after {
margin-left: 10px;
content: '';
width: 20px;
height: 20px;
background: svg-load('./assets/img/icon/ArrowRight.svg', stroke=#FFFF) no-repeat 100%;
background-size: cover;
transition: background 0.3s ease, width 0.3s ease;
}
&:hover {
color: var(--color-white);
border-bottom: 1px solid var(--color-white);
}
&:hover::after {
width: 40px;
}
}
&.m--underline {
text-decoration: underline;
} }
}
&.m--underline{
text-decoration: underline;
}
} }
@define-mixin a--color $color { @define-mixin a--color $color {
color: $color; color: $color;
border-color: rgba($color, 0.5); border-color: rgba($color, 0.5);
} }
@define-mixin table { @define-mixin table {
/* dummy */ /* dummy */
} }
@define-mixin base { @define-mixin base {
font: $font-size-base/$line-height-base $font-family-base; font: $font-size-base/$line-height-base $font-family-base;
color: $color-base; color: $color-base;
} }
@define-mixin format { @define-mixin format {
h1:not(.nostyle) { h1:not(.nostyle) {
@mixin h1; @mixin h1;
} }
h2:not(.nostyle) { h2:not(.nostyle) {
@mixin h2; @mixin h2;
} }
h3:not(.nostyle) { h3:not(.nostyle) {
@mixin h3; @mixin h3;
} }
h4:not(.nostyle) { h4:not(.nostyle) {
@mixin h4; @mixin h4;
} }
p:not(.nostyle) { p:not(.nostyle) {
@mixin p; @mixin p;
} }
ul:not(.nostyle) { ul:not(.nostyle) {
@mixin ul; @mixin ul;
} }
ol:not(.nostyle) { ol:not(.nostyle) {
@mixin ol; @mixin ol;
} }
hr:not(.nostyle) { hr:not(.nostyle) {
@mixin hr; @mixin hr;
} }
a:not(.nostyle) { a:not(.nostyle) {
@mixin a; @mixin a;
} }
table:not(.nostyle) { table:not(.nostyle) {
@mixin table; @mixin table;
} }
b:not(.nostyle), b:not(.nostyle),
strong:not(.nostyle) { strong:not(.nostyle) {
font-weight: bold; font-weight: bold;
} }
i:not(.nostyle), i:not(.nostyle),
em:not(.nostyle) { em:not(.nostyle) {
font-style: italic; font-style: italic;
} }
u:not(.nostyle), u:not(.nostyle),
ins:not(.nostyle) { ins:not(.nostyle) {
text-decoration: underline; text-decoration: underline;
} }
strike:not(.nostyle), strike:not(.nostyle),
del:not(.nostyle) { del:not(.nostyle) {
text-decoration: line-through; text-decoration: line-through;
} }
} }
@define-mixin text { @define-mixin text {
@mixin format; @mixin format;
font: $font-size-text/$line-height-text $font-family-text; font: $font-size-text/$line-height-text $font-family-text;
color: $color-text; color: $color-text;
} }

View File

@ -1,43 +1,81 @@
.footer{ .footer {
padding-bottom: var(--space-between-block); padding-bottom: var(--space-between-block);
width: 100%; width: 100%;
&__top{
padding-bottom: 80px;
margin-bottom: 80px;
border-bottom: 1px solid var(--color-white-opacity);
}
&__question{
display: flex;
align-items: center;
justify-content: space-between;
}
&__bottom{
display: flex;
justify-content: space-between;
}
&__menu{
display: grid;
grid-template-columns: var(--space-between-sections) var(--space-between-sections);
grid-template-rows: min-content min-content;
grid-column-gap: var(--space-between-sections);
grid-row-gap: var(--space-between-block);
&-item{
&__top {
padding-bottom: 80px;
margin-bottom: 80px;
border-bottom: 1px solid var(--color-white-opacity);
} }
&-link{
font-size: 1.2rem; &__question {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
@mixin responsive-xs {
align-items: flex-start;
flex-direction: column;
}
&-button {
margin-left: auto;
}
}
&__bottom {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
&__menu {
display: grid;
grid-template-columns: var(--space-between-sections) var(--space-between-sections);
grid-template-rows: fit-content fit-content;
grid-column-gap: var(--space-between-sections);
grid-row-gap: var(--space-between-block);
@mixin responsive-m {
width: 100%;
grid-row-gap: 10px;
grid-template-rows: min-content;
grid-template-columns: min-content min-content min-content;
margin-bottom: var(--space-between-block);
}
@mixin responsive-s {
display: flex;
flex-wrap: wrap;
}
&-item {
@mixin responsive-s {
width: 100%;
}
}
&-link {
font-size: 1.2rem;
}
}
&__social {
display: flex;
flex-wrap: wrap;
gap: var(--space-between-block);
@mixin responsive-m {
margin-bottom: var(--space-between-block);
grid-row-gap: 10px;
}
}
&__connection {
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-between;
gap: 1rem;
@mixin responsive-m {
width: 100%;
align-items: flex-start;
}
} }
}
&__social{
display: flex;
flex-wrap: wrap;
gap: var(--space-between-block);
}
&__connection{
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-between;
gap: 1rem;
}
} }

View File

@ -5,19 +5,39 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: start; align-items: start;
flex-wrap: wrap;
margin-bottom: var(--space-between-block);
row-gap: var(--space-between-block);
&-title{
margin-bottom: 0;
}
&-btn{
margin-left: auto;
@mixin responsive-xxs {
width: 100%;
}
}
} }
&__content { &__content {
display: flex; display: flex;
gap: 80px; gap: 80px;
@mixin responsive-m {
flex-direction: column;
}
} }
&__cover { &__cover {
width: 50%; width: 100%;
max-height: 640px; max-height: 640px;
background: url("./assets/img/bg/blog.svg") no-repeat center; background: url("./assets/img/bg/blog.svg") no-repeat center;
position: relative; position: relative;
z-index: 2; z-index: 2;
background-size: cover;
@mixin responsive-m {
height: calc(var(--base-content-size) / 2);
max-height: none;
}
} }
&__list { &__list {

View File

@ -118,7 +118,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: var(--space-between-sections); margin-bottom: var(--space-between-sections);
@mixin responsive-m { @mixin responsive-m {
gap: var(--space-between-block); gap: var(--space-between-block);
} }
@ -135,6 +135,10 @@
color: transparent; color: transparent;
background-clip: text; background-clip: text;
background-image: var(--linear-gradient); background-image: var(--linear-gradient);
@mixin responsive-s {
flex-direction: column;
gap: 10px;
}
&.m--circle { &.m--circle {
align-items: end; align-items: end;
@ -144,6 +148,12 @@
width: 130px; width: 130px;
height: 130px; height: 130px;
background: url("./assets/img/icon/circleGradient.svg") no-repeat center; background: url("./assets/img/icon/circleGradient.svg") no-repeat center;
@mixin responsive-s {
margin-right: auto;
width: 80px;
height: 80px;
background-size: contain;
}
} }
} }
@ -154,6 +164,9 @@
@mixin responsive-m { @mixin responsive-m {
width: 75%; width: 75%;
} }
@mixin responsive-s {
width: 100%;
}
} }
} }
} }
@ -163,6 +176,7 @@
@mixin responsive-m { @mixin responsive-m {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
flex-wrap: wrap;
gap: calc(var(--space-between-block) / 2); gap: calc(var(--space-between-block) / 2);
max-width: none; max-width: none;
} }
@ -171,11 +185,16 @@
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
font-size: 16px; font-size: 16px;
margin-bottom: 2.5rem;
position: relative; position: relative;
z-index: 2; z-index: 2;
&:not(&:last-child){
margin-bottom: var(--space-between-block);
}
@mixin responsive-m { @mixin responsive-m {
width: calc(100% / 3); width: calc((100% - var(--space-between-block)) / 3);
}
@mixin responsive-s {
width: 100%;
} }
&:before { &:before {
content: ''; content: '';
@ -234,10 +253,15 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-end; align-items: flex-end;
flex-wrap: wrap;
row-gap: var(--space-between-block);
} }
&--description { &--description {
max-width: 45%; max-width: 45%;
@mixin responsive-xs {
max-width: 100%;
}
} }
&--btns { &--btns {

View File

@ -5,16 +5,31 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: start; align-items: start;
flex-wrap: wrap;
&-title{
margin-bottom: 0;
}
} }
&__description{ &__description{
max-width: 60%; max-width: 60%;
margin-bottom: 2.5rem; margin-bottom: 2.5rem;
@mixin responsive-xxs {
max-width: none;
}
&.m--50{ &.m--50{
margin-bottom: 0; margin-bottom: 0;
max-width: 50%; max-width: 50%;
width: 100%; width: 100%;
} }
} }
&__link{
@mixin responsive-xxs {
order: 1;
margin: var(--space-between-block) 0;
width: 100%;
}
}
&__list{ &__list{
position: relative; position: relative;
padding-bottom: 10px; padding-bottom: 10px;
@ -52,6 +67,8 @@
transition: all .3s ease; transition: all .3s ease;
margin-right: auto; margin-right: auto;
color: var(--color-white); color: var(--color-white);
text-wrap: nowrap;
padding-right: 10px;
} }
&__btn{ &__btn{
transition: all .35s ease, visibility .0s ease; transition: all .35s ease, visibility .0s ease;

View File

@ -1,79 +1,122 @@
.team { .team {
margin-left: auto; margin-left: auto;
max-width: calc(100vw - ((100vw - var(--container)) / 2)); max-width: calc(100vw - ((100vw - var(--container)) / 2));
margin-bottom: var(--space-between-sections); margin-bottom: var(--space-between-sections);
position: relative;
z-index: 2;
&__header {
display: flex;
}
&__title {
margin-right: auto;
}
&__slider {
&:hover {
cursor: url("./assets/img/icon/cursorDragAndDrop.svg"), auto;
}
.swiper-wrapper {
}
}
&__item {
}
&__tools {
margin-top: 65px;
display: flex;
justify-content: space-between;
max-width: var(--container);
}
&__progress {
width: 100%;
height: 4px;
position: relative; position: relative;
max-width: 460px; z-index: 2;
background: var(--color-white-opacity); @mixin responsive-xl {
border-radius: 20px; padding: 0 0 0 20px;
overflow: hidden;
span {
background: var(--color-white);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform-origin: left top;
} }
}
&__cover { &__header {
margin-bottom: 0.5rem; display: flex;
height: 450px; max-width: var(--container);
overflow: hidden; margin-right: auto;
} padding: 0 50px 0;
margin-bottom: var(--space-between-block);
&__name { @mixin responsive-xl {
font-weight: 500; padding: 0 40px 0 0;
font-size: 1.5rem; column-gap: var(--space-between-block);
display: flex; }
flex-direction: column; @mixin responsive-s {
gap: 0.5rem; flex-wrap: wrap;
}
span {
font-weight: 400;
font-size: 1.125rem;
} }
}
&__description { &__title {
max-width: 820px; margin-bottom: 0;
} margin-right: auto;
text-wrap: nowrap;
}
&__slider {
&:hover {
cursor: url("./assets/img/icon/cursorDragAndDrop.svg"), auto;
}
.swiper-wrapper {
}
}
&__item {
}
&__tools {
margin-top: 65px;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
max-width: var(--container);
margin-right: auto;
row-gap: 1.5rem;
padding: 0 50px 0;
@mixin responsive-xl {
padding: 0 80px 0 35px;
}
@mixin responsive-l {
padding: 0 40px 0 0;
}
.m--link{
@mixin responsive-s {
width: 100%;
display: flex;
justify-content: flex-end;
}
}
}
&__progress {
width: 100%;
height: 4px;
position: relative;
max-width: 460px;
background: var(--color-white-opacity);
border-radius: 20px;
overflow: hidden;
@mixin responsive-s {
max-width: none;
}
span {
background: var(--color-white);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform-origin: left top;
}
}
&__cover {
margin-bottom: 0.5rem;
height: 450px;
overflow: hidden;
}
&__name {
font-weight: 500;
font-size: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
span {
font-weight: 400;
font-size: 1.125rem;
}
}
&__description {
max-width: 820px;
@mixin responsive-xl {
max-width: calc(100% - var(--space-between-block));
}
@mixin responsive-s {
max-width: none;
width: 100%;
}
}
} }

View File

@ -9,7 +9,7 @@ $color-primary: #5E5BFC;
--color-black: #232323; --color-black: #232323;
--color-white: #FFFFFF; --color-white: #FFFFFF;
--color-white-darker: #E7E7E7; --color-white-darker: #E7E7E7;
--color-white-opacity: #404145; --color-white-opacity: #BBB9CA;
--bg-wrapper-modal: #000000E5; --bg-wrapper-modal: #000000E5;
--color-primary: $color-primary; --color-primary: $color-primary;
--color-black-cc: #000000CC; --color-black-cc: #000000CC;
@ -34,6 +34,7 @@ $color-primary: #5E5BFC;
} }
@media (max-width: $document-width-m) { @media (max-width: $document-width-m) {
--container: $document-width-s; --container: $document-width-s;
--space-between-sections: calc(var(--base-fz) * 2.7);
} }
@media (max-width: $document-width-s) { @media (max-width: $document-width-s) {
--container: $document-width-xs; --container: $document-width-xs;

View File

@ -4,7 +4,7 @@
<h2 class="h2 m--white">Напишите нам</h2> <h2 class="h2 m--white">Напишите нам</h2>
<div class="footer__question"> <div class="footer__question">
<div class="text">Остались вопросы? Мы с радостью вам ответим!</div> <div class="text">Остались вопросы? Мы с радостью вам ответим!</div>
<button class="button m--white m--arrow">Написать</button> <button class="button m--white m--arrow footer__question-button">Написать</button>
</div> </div>
</div> </div>
<div class="footer__bottom"> <div class="footer__bottom">

View File

@ -100,8 +100,8 @@ export default {
{ {
$formkit: 'text', $formkit: 'text',
name: 'email', name: 'email',
label: 'придумайте логин', label: 'Ваша почта',
placeholder: 'Придумайте логин', placeholder: 'Ваша почта',
validation: 'required', validation: 'required',
outerClass: 'field--required' outerClass: 'field--required'
}, },
@ -118,8 +118,8 @@ export default {
{ {
$formkit: 'text', $formkit: 'text',
name: 'email', name: 'email',
label: 'логин', label: 'Почта',
placeholder: 'Логин', placeholder: 'Почта',
validation: 'required', validation: 'required',
outerClass: 'field--required' outerClass: 'field--required'
}, },

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="blog"> <div class="blog">
<div class="blog__header"> <div class="blog__header">
<h2 class="h2">Наш блог</h2> <h2 class="h2 blog__header-title">Наш блог</h2>
<button class="button m--arrow">Смотреть все</button> <button class="button m--arrow blog__header-btn">Смотреть все</button>
</div> </div>
<div class="blog__content"> <div class="blog__content">
<div class="blog__cover"></div> <div class="blog__cover"></div>

View File

@ -0,0 +1,26 @@
<template>
<ContentLoader
viewBox="0 0 1920 40"
:speed="2"
primaryColor="#bbb9ca"
secondaryColor="#ecebeb"
>
<rect x="68" y="18" rx="2" ry="2" width="25" height="5" />
<rect x="444" y="11" rx="2" ry="2" width="75" height="10" />
<rect x="68" y="11" rx="2" ry="2" width="25" height="5" />
<rect x="45" y="29" rx="2" ry="2" width="538" height="6" />
<rect x="9" y="10" rx="2" ry="2" width="25" height="25" />
<rect x="22" y="21" rx="0" ry="0" width="6" height="2" />
<circle cx="54" cy="17" r="8" />
<rect x="523" y="11" rx="2" ry="2" width="58" height="10" />
<rect x="101" y="11" rx="2" ry="2" width="13" height="13" />
</ContentLoader>
</template>
<script>
import { ContentLoader } from "vue-content-loader"
export default {
name: 'playLoader',
components: [ContentLoader]
}
</script>

View File

@ -1,147 +1,247 @@
<template> <template>
<div class="player"> <div class="player">
<div class="player__cover"> <playLoader v-if="false"/>
<img :src="currentPlay.art" alt="player"/> <template v-else>
</div> <div class="player__cover">
<div class="player__content"> <img :src="currentPlay.art" alt="player"/>
<div class="player__top"> </div>
<button v-if="currentPlay.isPlay" @click="handlerPause" class="button player__btn m--pause"> <div class="player__content">
</button> <div class="player__top">
<button v-else @click="handlerPlay" class="button player__btn m--play"> <button v-if="currentPlay.isPlay" @click="handlerPause" class="button player__btn m--pause">
</button> </button>
<div class="player__executor"> <button v-else @click="handlerPlay" class="button player__btn m--play">
{{ currentPlay.title || '—' }} </button>
<span>{{ currentPlay.artist || '—' }}</span> <div class="player__executor">
</div> {{ currentPlay.title || '—' }}
<div class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites"> <span>{{ currentPlay.artist || '—' }}</span>
</div> </div>
<div class="player__tools"> <div class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites">
<FormKit </div>
v-model="isLive" <div class="player__tools">
type="toggle" <FormKit
label="Включить мою музыку" v-model="isUserMusic"
@change="changeLive" type="toggle"
/> label="Включить мою музыку"
<div class="player__volume"> :disabled="!user"
<span @click="setVolume"/> />
<input type="range" v-model="player.volume" @change="changeVolume"> <div class="player__volume">
</div> <span @click="setVolume"/>
</div> <input type="range" v-model="player.volume" @change="changeVolume">
</div> </div>
<div class="player__bottom"> </div>
<div class="player__time m--ether"> </div>
Эфир <div class="player__bottom">
</div> <div class="player__time" :class="!isUserMusic&&'m--ether'">
<div class="player__progress"> <template v-if="isUserMusic">
<input :disabled="player.live" type="range" v-model="player.progress"> {{ getTime(playerInfo.currentTime) }}/{{ getTime(playerInfo.duration) }}
</div> </template>
</div> <template v-else>
</div> Эфир
</div> </template>
</div>
<div class="player__progress">
<input :disabled="!isUserMusic" type="range" v-model="playerInfo.progress">
</div>
</div>
</div>
</template>
</div>
</template> </template>
<script> <script>
import {audio as Player, app} from "@/services"; import {audio as Player, app} from "@/services";
import PlayLoader from "components/player-loader.vue";
export default { export default {
name: 'player', name: 'player',
data() { components: {PlayLoader},
return { data() {
audioUrl: 'http://82.97.242.49:18000/radio.mp3', return {
isFavorites: false, audioUrl: 'http://82.97.242.49:18000/radio.mp3',
isPlayRadio: true, isFavorites: false,
connection: null, isPlayRadio: true,
isLive: !this.$store.state.currentPlay.live, connection: null,
} isUserMusic: !this.$store.state.currentPlay.live,
}, playerInfo: {
computed: { progress: 0,
user() { currentTime: 0,
return this.$store.state.user; duration: 0
}, }
currentPlay() { }
return this.$store.state.currentPlay },
}, computed: {
player() { user() {
return this.$store.state.player return this.$store.state.user;
} },
}, currentPlay() {
watch: { return this.$store.state.currentPlay
'currentPlay': { },
immediate: false, player() {
handler() { return this.$store.state.player
if (this.isLive!==!this.currentPlay.live){ },
this.isLive = !this.currentPlay.live; userSongList() {
} return this.$store.state.userFavorite?.songs || []
}, }
}, },
}, watch: {
created() { 'currentPlay': {
this.connectionPlayer(); immediate: false,
}, handler(to, from) {
mounted() { if (this.isUserMusic !== !this.currentPlay.live) {
if (!this.player.target) { this.isUserMusic = !this.currentPlay.live;
this.$store.dispatch('initPlayer'); }
} if (to.id !== from.id && this.user.id) {
}, this.checkSongIsFavorite();
methods: { }
connectionPlayer() { if (!this.currentPlay.live && to.id !== from.id) {
if (this.connection) { this.getAudio(this.userSongList[0].azura_id);
this.connection.removePlay(); }
} },
this.connection = new Player(); },
this.connection.init(); 'isUserMusic': {
this.connection.onHandler(this.getPlaying); immediate: false,
}, handler() {
getPlaying(e) { if (this.isUserMusic === this.currentPlay.live) {
const jsonData = JSON.parse(e.data) this.changeLive();
if (jsonData?.pub?.data) { }
const data = jsonData?.pub?.data; },
if (this.currentPlay.live) { },
if (data.np.station.listen_url !== this.player.target.src) { },
this.$store.dispatch('changePlayer', data.np.station.listen_url); created() {
} this.connectionPlayer();
this.$store.dispatch('setCurrentPlay', {...data.np.now_playing.song, live: true}); if (this.user.id) {
} this.checkSongIsFavorite();
} }
}, },
updateProgress() { mounted() {
console.log(this.$refs.player.currentTime) this.$store.dispatch('initPlayer');
console.log(this.$refs.player.duration)
}, this.playerInfo.progress = this.currentPlay.live ? 100 : 0;
handlerPlay() {
this.$store.dispatch('handlerPlayer', {play: true}); if (!this.currentPlay.live) {
}, this.$store.dispatch('setCurrentPlay', {...this.userSongList[0], live: false});
handlerPause() { this.getAudio(this.userSongList[0].azura_id);
this.$store.dispatch('handlerPlayer', {pause: true}); if (this.player.target){
}, this.player.target.addEventListener('timeupdate',this.updateProgress)
handlerFavorites() { }
if (this.user?.id) { }
this.isFavorites = !this.isFavorites; },
const params = {...this.currentPlay, azura_id: this.currentPlay.id}; methods: {
app.createFavoriteForUser(params).then(() => { connectionPlayer() {
if (this.connection) {
}) this.connection.removePlay();
} else { }
this.$emit('shopAuthentication', true) this.connection = new Player();
} this.connection.init();
this.connection.onHandler(this.getPlaying);
}, },
setVolume() { checkSongIsFavorite() {
this.$store.dispatch('handlerPlayer', {volume: 100}); app.getCheckFavoriteSong(this.currentPlay.azura_id || this.currentPlay.id).then(res => {
}, this.isFavorites = true;
changeVolume() { }).catch(err => {
this.$store.dispatch('handlerPlayer', {volume: 100}); this.isFavorites = false;
}, console.error(err)
changeLive(e) { })
console.log(e) },
if (this.currentPlay.live) { getPlaying(e) {
this.$store.dispatch('setCurrentPlay', {live: false}); const jsonData = JSON.parse(e.data)
console.log('избранное') if (jsonData?.pub?.data) {
} else { const data = jsonData?.pub?.data;
this.$store.dispatch('setCurrentPlay', {live: true}); if (this.currentPlay.live) {
console.log('поток') if (data.np.station.listen_url !== this.player.target.src) {
} console.log('data.np.station.listen_url', data.np.station.listen_url)
} this.$store.dispatch('changePlayer', data.np.station.listen_url);
} }
this.$store.dispatch('setCurrentPlay', {
...this.currentPlay,
...data.np.now_playing.song,
live: true
});
}
}
},
updateProgress(e) {
this.playerInfo = {
progress: this.player.target.currentTime / this.player.target.duration * 100,
currentTime: this.player.target.currentTime,
duration: this.player.target.duration
}
},
handlerPlay() {
console.log(this.player.target.src)
this.$store.dispatch('handlerPlayer', {play: true});
},
handlerPause() {
this.$store.dispatch('handlerPlayer', {pause: true});
},
getSongList() {
app.getFavoriteList().then(res => {
this.$store.dispatch('setUserFavorite', {songs: res})
}).catch(err => {
console.error(err)
})
},
handlerFavorites() {
if (this.user?.id) {
const params = {...this.currentPlay, azura_id: this.currentPlay.id};
if (!this.isFavorites) {
app.createFavoriteForUser(params).then(() => {
this.isFavorites = !this.isFavorites;
this.getSongList();
}).catch(err => {
console.error(err)
})
} else {
console.log(params)
// app.removeFavoriteForUser(params).then(()=>{
// this.isFavorites = !this.isFavorites;
// this.getSongList();
// }).catch(err=>{
// console.error(err)
// })
}
} else {
this.$emit('shopAuthentication', true)
}
},
setVolume() {
this.$store.dispatch('handlerPlayer', {volume: 100});
},
changeVolume() {
this.$store.dispatch('handlerPlayer', {volume: 100});
},
getAudio(id) {
app.getAudio(id).then(res => {
const blob = new Blob([res], {type: 'application/audio'});
const audioUrl = URL.createObjectURL(blob);
this.$store.dispatch('changePlayer', audioUrl);
}).catch(err => {
console.debug(err)
})
},
changeLive() {
if (this.currentPlay.live) {
console.log('избранное')
this.getAudio(this.userSongList[0].azura_id);
this.playerInfo.progress = 0;
this.player.target.addEventListener('timeupdate', this.updateProgress)
this.$store.dispatch('setCurrentPlay', {...this.userSongList[0], live: false});
} else {
this.playerInfo.progress = 100;
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, live: true});
console.log('поток')
}
},
getTime(value) {
let minutes = Math.floor(value / 60);
let seconds = Math.round(value % 60);
let paddedMinutes = minutes < 10 ? "0" + minutes : minutes;
let paddedSeconds = seconds < 10 ? "0" + seconds : seconds;
return `${paddedMinutes}:${paddedSeconds}`;
}
}
} }
</script> </script>

View File

@ -1,42 +1,34 @@
<template> <template>
<div class="rubric-block"> <div class="rubric-block">
<div class="rubric-block__header"> <div class="rubric-block__header">
<h2 class="h2"> <h2 class="h2 rubric-block__header-title">
Рубрики Рубрики
</h2> </h2>
<button class="button m--arrow" v-if="$route.name !== 'rubric'" @click="next('rubric')">Смотреть все</button> <button class="button m--arrow rubric-block__link" v-if="$route.name !== 'rubric'" @click="next('rubric')">Смотреть все</button>
<div class="p rubric-block__description">
IT-радио - это уникальная платформа для обмена опытом, знаниями и обсуждения актуальных вопросов, связанных с разработкой программного обеспечения, искусственного интеллекта, интернета вещей и других направлений IT-индустрии
</div>
</div> </div>
<div class="p rubric-block__description"> <template v-if="showLoader">
IT-радио - это уникальная платформа для обмена опытом, знаниями и обсуждения актуальных вопросов, связанных с разработкой программного обеспечения, искусственного интеллекта, интернета вещей и других направлений IT-индустрии <div class="loader">
</div> <div class="spinner"/>
<div class="rubric-block__list"> Загрузка данных
<div class="rubric-block__item"> </div>
<div class="title rubric-block__title">Новости</div> </template>
<div class="p rubric-block__description m--50">Новости из мира цифровых и около цифровых технологий, рассказанные понятным языком.</div> <div v-else class="rubric-block__list">
<button class="button m--arrow rubric-block__btn" @click="showModalRubric('news')">Узнать больше</button> <div class="rubric-block__item" v-for="rubrik in rubriks" :key="`rubrik_${rubrik.id}`">
</div> <div class="title rubric-block__title">{{rubrik.name}}</div>
<div class="rubric-block__item"> <div class="p rubric-block__description m--50">{{rubrik.title}}</div>
<div class="title rubric-block__title">Подкасты</div> <button class="button m--arrow rubric-block__btn" @click="showModalRubric(rubrik.id)">Узнать больше</button>
<div class="p rubric-block__description m--50">Диалоги, записанные нашей командой с интересными гостями из мира IT.</div>
<button class="button m--arrow rubric-block__btn" @click="showModalRubric('podcast')">Узнать больше</button>
</div>
<div class="rubric-block__item">
<div class="title rubric-block__title">Поговори с ИИ</div>
<div class="p rubric-block__description m--50">Общаемся с искусственным интеллектом и нейросетями. Пытаемся понять на что он способен и что может.</div>
<button class="button m--arrow rubric-block__btn" @click="showModalRubric('AI')">Узнать больше</button>
</div>
<div class="rubric-block__item">
<div class="title rubric-block__title">Ликбез</div>
<div class="p rubric-block__description m--50">Ликвидация безграмотности в сфере IT. Объяснить понятия так, чтобы понял и ребёнок и подросток и старшее поколение. Рубрика, направленная на повышение уровня осведомленности в IT.</div>
<button class="button m--arrow rubric-block__btn" @click="showModalRubric('educational')">Узнать больше</button>
</div> </div>
</div> </div>
</div> </div>
<RubricModal :showModal="isShowModalRubric" @hideModal="hiddenModalRubric" :ModalTemplate="ModalTemplate"/> <RubricModal :showModal="isShowModalRubric" @hideModal="hiddenModalRubric" :selectRubric="ModalTemplate"/>
</template> </template>
<script> <script>
import RubricModal from "@/components/rubric-modal.vue"; import RubricModal from "@/components/rubric-modal.vue";
import {app} from "@/services";
export default { export default {
name: 'rubric-block', name: 'rubric-block',
@ -44,10 +36,25 @@ export default {
data(){ data(){
return{ return{
isShowModalRubric: false, isShowModalRubric: false,
ModalTemplate:null ModalTemplate:null,
} rubriks: [],
showLoader: false,
}
}, },
methods:{ created() {
this.getRubriks();
},
methods:{
getRubriks() {
this.showLoader = true;
app.getRubriks().then((data) => {
this.showLoader = false;
this.rubriks = data;
}).catch(err => {
this.showLoader = false;
console.log(err)
})
},
showModalRubric(key){ showModalRubric(key){
this.ModalTemplate = key this.ModalTemplate = key
this.isShowModalRubric = true; this.isShowModalRubric = true;

View File

@ -1,69 +1,97 @@
<template> <template>
<vue-final-modal <vue-final-modal
v-model="show" v-model="show"
class="modal__container m--right" class="modal__container m--right"
content-class="modal__block m--half rubric-modal" content-class="modal__block m--half rubric-modal"
content-transition="vfm-fade" content-transition="vfm-fade"
overlay-transition="vfm-fade" overlay-transition="vfm-fade"
:clickToClose="false" :clickToClose="false"
@click-outside="$emit('hideModal')" @click-outside="$emit('hideModal')"
> >
<div class="rubric-modal__header"> <template v-if="showLoader">
<div class="title m--white rubric-modal__title"> <div class="loader">
<template v-if="ModalTemplate==='news'">Новости</template> <div class="spinner"/>
<template v-else-if="ModalTemplate==='podcast'">Подкасты</template> Загрузка данных
<template v-else-if="ModalTemplate==='AI'">Поговори с ИИ</template> </div>
<template v-else-if="ModalTemplate==='educational'">Ликбез</template> </template>
</div> <template v-else>
<button <div class="rubric-modal__header">
class="button modal__close rubric-modal__close" <div class="title m--white rubric-modal__title">
@click="$emit('hideModal')" {{rubrik.name}}
> </div>
</button> <button
</div> class="button modal__close rubric-modal__close"
<div class="rubric-modal__cover"> @click="$emit('hideModal')"
<img src="@/assets/img/icon/remove-rubrics.png" alt=""/> >
</div> </button>
<div class="rubric-modal__description"> </div>
<template v-if="ModalTemplate==='news'"> <div class="rubric-modal__cover">
В этой рубрике будут выходить ежедневные и еженедельные новостные выпуски, освещающие ключевые события в мире IT, включая новые разработки, релизы продуктов, изменения в законодательстве, касающиеся технологий, и другие важные события.<br/><br/> Так же будем выдавать аналитические материалы - глубокие и не очень глубокие обзоры, в которых рассматриваются тенденции развития IT-индустрии, анализируются стратегические направления развития крупных компаний и перспективы новых технологий <img :src="`${selfUrl}${rubrik.img}`" alt=""/>
</template> </div>
<template v-else-if="ModalTemplate==='podcast'"> <div class="rubric-modal__description">
В подкастах мы будем задавать вопросы айтишникам, специалистам из около айтишной среды, цифровым музыкантам, чиновникам от IT, бизнесменам, геймерам и киберспортсменам, криптовалютчикам и сами будем отвечать на вопросы простых людей, которые хотят разобраться в нашей сфере, которая пронизывает все сферы современной жизни. А если сами не сможем ответить, то будем искать тех, кто сможет ответить. {{rubrik.description}}
</template> </div>
<template v-else-if="ModalTemplate==='AI'"> <button class="button m--fit-content m--white m--arrow" v-if="user.id">Написать</button>
Редакция IT-Радио собирается за круглым столом и задаёт ИИ вопросы, которые приходят к нам на почту на разные темы.<br/><br/> Цель - понять насколько далеко ИИ уходит в своём развитии от человека, дать ответы на вопросы. Попытаемся разобрать ответы искусственного интеллекта, дать свои комментарии, дополнить. Попытаемся понять его логику и логику его разработчиков, которую закладывали в работу нейросети. </template>
</template> </vue-final-modal>
<template v-else-if="ModalTemplate==='educational'">
Будем рассказывать что такое IT-сфера. Какие у неё составляющие. Кого можно назвать айтишником, а кого нет и почему. Почему кому-то сложно понять IT и при чём тут точные науки.
</template>
</div>
<button class="button m--fit-content m--white m--arrow">Написать</button>
</vue-final-modal>
</template> </template>
<script> <script>
import {app} from "@/services";
import {selfUrl} from '@/settings';
export default { export default {
name: 'RubricModal', name: 'RubricModal',
props: { props: {
showModal: { showModal: {
type: Boolean, type: Boolean,
default() { default() {
return false; return false;
} }
}, },
ModalTemplate:{ selectRubric: {
type: String, type: String,
default() { default() {
return ''; return '';
} }
}, },
}, },
computed: { data() {
show() { return {
return this.showModal; selfUrl,
}, rubrik: {},
}, showLoader: false
}
},
computed: {
show() {
return this.showModal;
},
user() {
return this.$store.state.user;
},
},
watch: {
'selectRubric': {
handler() {
if (this.selectRubric){
this.getRubrik();
}
}
}
},
methods: {
getRubrik() {
this.showLoader = true;
app.getRubrik(this.selectRubric).then((data) => {
this.showLoader = false;
this.rubrik = data[0];
}).catch(err => {
this.showLoader = false;
console.log(err)
})
},
}
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="song-item" :class="[currentPlay.id===song.id&&'m--select']" @click="handlerSelectSong"> <div class="song-item" :class="[selectSong&&'m--select']" @click="handlerSelectSong">
<div class="song-item__selected" :class="[!isPlay&&'m--stop']"> <div class="song-item__selected" :class="[!isPlay&&'m--stop']">
<svg width="33" height="28" viewBox="0 0 33 28" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="33" height="28" viewBox="0 0 33 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="" d="M0 15C0 13.6193 1.11929 12.5 2.5 12.5C3.88071 12.5 5 13.6193 5 15V27.5H0V15Z" fill="#7138F4"/> <path class="" d="M0 15C0 13.6193 1.11929 12.5 2.5 12.5C3.88071 12.5 5 13.6193 5 15V27.5H0V15Z" fill="#7138F4"/>
@ -10,9 +10,9 @@
</svg> </svg>
</div> </div>
<div> <div>
<button v-if="isPlay" @click="handlerPause" class="button song-item__btn m--pause"> <button v-if="isPlay" @click.stop="handlerPause" class="button song-item__btn m--pause">
</button> </button>
<button v-else @click="handlerPlay" class="button song-item__btn m--play"> <button v-else @click.stop="handlerPlay" class="button song-item__btn m--play">
</button> </button>
</div> </div>
<div class="song-item__info"> <div class="song-item__info">
@ -31,9 +31,9 @@ export default {
name: 'song-item', name: 'song-item',
props:{ props:{
selectSong:{ selectSong:{
type: Number, type: Boolean,
default(){ default(){
return null return false
} }
}, },
song:{ song:{
@ -47,7 +47,7 @@ export default {
default(){ default(){
return false return false
} }
} },
}, },
watch: { watch: {
'playSong': { 'playSong': {
@ -62,20 +62,15 @@ export default {
isPlay: this.playSong isPlay: this.playSong
} }
}, },
computed:{
currentPlay(){
return this.$store.state.currentPlay
}
},
methods:{ methods:{
handlerPlay() { handlerPlay() {
this.isPlay = true; this.$emit('playSong', {...this.song, live: false, isPlay: true,})
}, },
handlerPause() { handlerPause() {
this.isPlay = false; this.$emit('pauseSong', {...this.song, live: false, isPlay: false,})
}, },
handlerSelectSong(){ handlerSelectSong(){
this.$store.dispatch('setCurrentPlay', {...this.song, live: false}); this.$emit('selectSong', {...this.song, live: false})
} }
} }
} }

View File

@ -4,6 +4,11 @@
v-for="song in songList" v-for="song in songList"
:key="song" :key="song"
:song="song" :song="song"
:playSong="!currentPlay.live && song.id === currentPlay.id? currentPlay.isPlay: false"
:selectSong="!currentPlay.live && song.id === currentPlay.id"
@selectSong="handlerSelectSong"
@playSong="handlerPlaySong"
@pauseSong="handlerPauseSong"
/> />
</div> </div>
</template> </template>
@ -23,6 +28,22 @@ export default {
data() { data() {
return {} return {}
}, },
methods: {} computed: {
currentPlay() {
return this.$store.state.currentPlay
}
},
methods: {
handlerSelectSong(params) {
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, ...params});
},
handlerPlaySong(params) {
this.$store.dispatch('setCurrentPlay', params);
},
handlerPauseSong(params) {
this.$store.dispatch('setCurrentPlay', params);
},
}
} }
</script> </script>

View File

@ -1,80 +1,98 @@
<template> <template>
<div class="team"> <div class="team">
<div class="team__header"> <div class="team__header">
<h2 class="h2 team__title"> <h2 class="h2 team__title">
Наша команда Наша команда
</h2> </h2>
<div class="team__description"> <div class="team__description">
На IT волне команда профессионалов неутомимо трудится, чтобы дарить слушателям самые свежие и актуальные На IT волне команда профессионалов неутомимо трудится, чтобы дарить слушателям самые свежие и актуальные
новости из мира технологий, отвечать на их вопросы и обсуждать горячие темы на IT радио. новости из мира технологий, отвечать на их вопросы и обсуждать горячие темы на IT радио.
</div> </div>
</div> </div>
<template v-if="showLoader"> <template v-if="showLoader">
<div class="loader"> <div class="loader">
<div class="spinner" /> Загрузка данных <div class="spinner"/>
Загрузка данных
</div> </div>
</template> </template>
<Swiper <Swiper
v-else v-else
:slides-per-view="4" :slides-per-view="4"
:space-between="20" :space-between="20"
:modules="modules" :modules="modules"
:pagination="{ :pagination="{
el: '.team__progress', el: '.team__progress',
clickable: true, clickable: true,
type: 'progressbar', type: 'progressbar',
}" }"
class="team__slider" :breakpoints="{
> 0: {
<SwiperSlide class="team__item" v-for="employee in team" :key="employee.id"> slidesPerView: 1,
<div class="team__cover"> },
<img :src="`${selfUrl + employee.img_person}`" alt="user"/> 450: {
</div> slidesPerView: 1.5,
<div class="team__name"> },
{{employee.name}} {{employee.last_name}} 768: {
<span>{{employee.position}}</span> slidesPerView: 2.5,
</div> },
</SwiperSlide> 1020:{
</Swiper> slidesPerView: 3,
<div class="team__tools"> },
<div class="team__progress" ref="progressBar"> 1280: {
<span></span> slidesPerView: 4,
</div> },
<router-link :to="{name: 'about'}" class="m--link"> }"
Больше о нас class="team__slider"
</router-link> >
</div> <SwiperSlide class="team__item" v-for="employee in team" :key="employee.id">
</div> <div class="team__cover">
<img :src="`${selfUrl + employee.img_person}`" alt="user"/>
</div>
<div class="team__name">
{{ employee.name }} {{ employee.last_name }}
<span>{{ employee.position }}</span>
</div>
</SwiperSlide>
</Swiper>
<div class="team__tools">
<div class="team__progress" ref="progressBar">
<span></span>
</div>
<router-link :to="{name: 'about'}" class="m--link">
Больше о нас
</router-link>
</div>
</div>
</template> </template>
<script> <script>
import 'swiper/css'; import 'swiper/css';
import {Swiper, SwiperSlide} from "swiper/vue"; import {Swiper, SwiperSlide} from "swiper/vue";
import {Pagination, Scrollbar} from "swiper/modules"; import {Pagination, Scrollbar} from "swiper/modules";
import { app } from "@/services"; import {app} from "@/services";
import {selfUrl} from '@/settings'; import {selfUrl} from '@/settings';
export default { export default {
name: 'team', name: 'team',
components: {Swiper, SwiperSlide}, components: {Swiper, SwiperSlide},
data() { data() {
return { return {
selfUrl, selfUrl,
team: [], team: [],
showLoader: false, showLoader: false,
modules: [Scrollbar, Pagination], modules: [Scrollbar, Pagination],
} }
}, },
created() { created() {
this.getTeams(); this.getTeams();
}, },
methods:{ methods: {
getTeams(){ getTeams() {
this.showLoader = true; this.showLoader = true;
app.getTeams().then((data)=>{ app.getTeams().then((data) => {
this.showLoader = false; this.showLoader = false;
this.team = data; this.team = data;
}).catch(err=>{ }).catch(err => {
this.showLoader = false; this.showLoader = false;
console.log(err) console.log(err)
}) })

View File

@ -44,7 +44,8 @@ export default route(function (/* { store, ssrContext } */) {
if (store.state.user && store.state.user.id) { if (store.state.user && store.state.user.id) {
next(); next();
} else { } else {
next({ name: 'auth' }); next({ name: 'home' });
this.$store.dispatch('setShowAuthModal', true);
} }
} else { } else {
next(); next();

View File

@ -34,6 +34,22 @@ export default class extends REST {
throw new RESTError(error, 'Ошибка при получении команды'); throw new RESTError(error, 'Ошибка при получении команды');
}); });
} }
static getCheckFavoriteSong(id){
return this._get(`radio/song/check_is_favorite/${id}`, {}, {}).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при проверке песни');
});
}
static getAudio(id){
return this._get(`radio/song/get_audio/${id}`, {}, {}, false, true).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получениии песни');
});
}
static createFavoriteForUser(params){ static createFavoriteForUser(params){
return this._post(`radio/song/add_favorite`, {}, params).then((data) => { return this._post(`radio/song/add_favorite`, {}, params).then((data) => {
return data; return data;
@ -42,6 +58,14 @@ export default class extends REST {
}); });
} }
static removeFavoriteForUser(params){
return this._post(`radio/song/delete_song`, {}, params).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получении плейлистов');
});
}
static getFavoriteList(params){ static getFavoriteList(params){
return this._get(`radio/song`, {}, params).then((data) => { return this._get(`radio/song`, {}, params).then((data) => {
return data; return data;
@ -49,7 +73,20 @@ export default class extends REST {
throw new RESTError(error, 'Ошибка при получении плейлистов'); throw new RESTError(error, 'Ошибка при получении плейлистов');
}); });
} }
static getRubriks() {
return this._get(`radio/rubriks`, {}, {}).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получении рубрик');
});
}
static getRubrik(id) {
return this._get(`radio/rubriks/${id}`, {}, {}).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получении рубрик');
});
}
@ -69,12 +106,4 @@ export default class extends REST {
throw new RESTError(error, 'Ошибка при получении плейлистов'); throw new RESTError(error, 'Ошибка при получении плейлистов');
}); });
} }
static getRubriks(station, params) {
return this._get(`radio.mp3`, params, {}).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получении плейлистов');
});
}
} }

View File

@ -35,8 +35,8 @@ class REST {
static get settings() { static get settings() {
throw new Error('settings must be overridden'); throw new Error('settings must be overridden');
} }
static _get(url, params={}, extraParams, use_cache=false) { static _get(url, params={}, extraParams, use_cache=false, isBlob=false) {
return this._request('get', url, params, {}, {}, extraParams, use_cache); return this._request('get', url, params, {}, {}, extraParams, use_cache, isBlob);
} }
static _post(url, params, data) { static _post(url, params, data) {
return this._request('post', url, params, data); return this._request('post', url, params, data);
@ -50,7 +50,7 @@ class REST {
static _delete(url, params, data) { static _delete(url, params, data) {
return this._request('delete', url, params, data); return this._request('delete', url, params, data);
} }
static _request(method, url, params={}, data={}, extraData={}, extraParams={}, use_cache=false) { static _request(method, url, params={}, data={}, extraData={}, extraParams={}, use_cache=false, isBlob=false) {
let cache_key = null; let cache_key = null;
return ajax.request({ return ajax.request({
method, method,
@ -59,7 +59,8 @@ class REST {
data, data,
extraData, extraData,
extraParams, extraParams,
headers: this._getAuthHeaders() headers: this._getAuthHeaders(),
responseType: this._getResponseType(isBlob),
}).then((response) => { }).then((response) => {
if (cache_key) { if (cache_key) {
cache.set(cache_key, response.data); cache.set(cache_key, response.data);
@ -67,6 +68,11 @@ class REST {
return response.data; return response.data;
}); });
} }
static _getResponseType(value){
if (value) {
return 'arraybuffer'
}
}
static _getAuthHeaders() { static _getAuthHeaders() {
if (store.state.token) { if (store.state.token) {
return { 'Authorization': `Bearer ${store.state.token}` }; return { 'Authorization': `Bearer ${store.state.token}` };

View File

@ -1,4 +1,4 @@
import { createStore } from 'vuex' import {createStore} from 'vuex'
import VuexPersist from 'vuex-persist'; import VuexPersist from 'vuex-persist';
const vuexPersist = new VuexPersist({ const vuexPersist = new VuexPersist({
@ -9,7 +9,7 @@ const vuexPersist = new VuexPersist({
// Vue.use(Vuex); // Vue.use(Vuex);
export default createStore({ export default createStore({
state () { state() {
return { return {
token: null, token: null,
refreshToken: null, refreshToken: null,
@ -18,11 +18,18 @@ export default createStore({
station: { station: {
id: 1 id: 1
}, },
currentPlay: {}, currentPlay: {
player:{ isPlay: false
},
player: {
target: null, target: null,
volume: 50, volume: 50,
live: true, live: true,
},
userFavorite: {
podcast: [],
playlist: [],
songs: []
} }
} }
}, },
@ -39,38 +46,55 @@ export default createStore({
state.token = null; state.token = null;
state.refreshToken = null; state.refreshToken = null;
}, },
setCurrentPlay(state, song){ setCurrentPlay(state, song) {
state.currentPlay = song; state.currentPlay = song;
}, },
setShowAuthModal(state, show){ setShowAuthModal(state, show) {
state.showAuthModal = show state.showAuthModal = show
}, },
setPlayer(state, params){ setPlayer(state, params) {
state.player = {...state.player,...params} state.player = {...state.player, ...params}
}, },
initPlayer(state){ initPlayer(state) {
state.player.target = document.createElement('audio') state.player.target = document.createElement('audio')
state.player.target.src = ''; state.player.target.src = '';
state.player.target.preload = 'auto'; state.player.target.preload = 'auto';
state.player.target.controls = true; state.player.target.controls = true;
console.log('initPlayer',state.player.target) console.log('initPlayer', state.player.target)
}, },
changePlayer(state, params){ changePlayer(state, params) {
const awaitPlay = () => {
if (state.player.target.readyState >= 4) {
state.player.target.play();
state.player.target.removeEventListener('canplaythrough', awaitPlay);
} else {
awaitPlay();
}
}
state.player.target.src = params; state.player.target.src = params;
state.player.src = params;
if (state.currentPlay.isPlay){
state.player.target.addEventListener('canplaythrough', awaitPlay)
}
}, },
handlerPlayer(state, params){ handlerPlayer(state, params) {
if (params.pause){ if (params.pause) {
state.currentPlay.isPlay = false; state.currentPlay.isPlay = false;
state.player.target.pause(); state.player.target.pause();
} }
if (params.play){ if (params.play) {
state.currentPlay.isPlay = true; state.currentPlay.isPlay = true;
console.log(state.player.target.readyState)
state.player.target.play(); state.player.target.play();
} }
if (params.volume){ if (params.volume) {
state.player.target.volume = params.volume; state.player.target.volume = params.volume;
} }
}, },
setUserFavorite(state, params) {
state.userFavorite = {...state.userFavorite, ...params}
}
}, },
actions: { actions: {
setToken(context, tokens) { setToken(context, tokens) {
@ -83,24 +107,26 @@ export default createStore({
context.commit('user', {}); context.commit('user', {});
context.commit('removeToken'); context.commit('removeToken');
}, },
setCurrentPlay(context, song){ setCurrentPlay(context, song) {
context.commit('setCurrentPlay', song); context.commit('setCurrentPlay', song);
}, },
setShowAuthModal(context, show){ setShowAuthModal(context, show) {
context.commit('setShowAuthModal', show); context.commit('setShowAuthModal', show);
}, },
setPlayer(context, params){ setPlayer(context, params) {
context.commit('setPlayer', params); context.commit('setPlayer', params);
}, },
initPlayer(context){ initPlayer(context) {
context.commit('initPlayer'); context.commit('initPlayer');
}, },
handlerPlayer(context, params){ handlerPlayer(context, params) {
context.commit('handlerPlayer', params); context.commit('handlerPlayer', params);
}, },
changePlayer(context, params){ changePlayer(context, params) {
context.commit('changePlayer', params); context.commit('changePlayer', params);
} },
setUserFavorite(context, params) {
context.commit('setUserFavorite', params);
},
} }
}); });

View File

@ -1,24 +1,25 @@
<template> <template>
<div class="home"> <div class="home">
<div class="home__meaning" ref="targetWrapper"> <div class="home__meaning" ref="targetWrapper">
<div class="app__content"> <div class="app__content">
<p class="text home__subtitle"> <p class="text home__subtitle">
Мы цифровое <span>онлайн радио.</span><br/> Мы цифровое <span>онлайн радио.</span><br/>
Помогаем разобраться в том, что такое <span>IT.</span><br/> Помогаем разобраться в том, что такое <span>IT.</span><br/>
Находимся в <span>Челябинске</span>, но вещаем на весь <span>Мир</span><br/> Находимся в <span>Челябинске</span>, но вещаем на весь <span>Мир</span><br/>
</p> </p>
<h1 class="home__title" ref="targetTitle"> <h1 class="home__title" ref="targetTitle">
IT-Радио <span id="targetTitleSpan">радиостанция про сферу</span> технологий <br/> и развитие <span id="targetTitleSpan">в IT</span> IT-Радио <span id="targetTitleSpan">радиостанция про сферу</span> технологий <br/> и развитие
<span id="targetTitleSpan">в IT</span>
<!-- IT Радио --> <!-- IT Радио -->
<!-- <span id="targetTitleSpan">радиостанция</span>--> <!-- <span id="targetTitleSpan">радиостанция</span>-->
<!-- <br/>--> <!-- <br/>-->
<!-- <span id="targetTitleSpan">про сферу</span> технологий<br/>--> <!-- <span id="targetTitleSpan">про сферу</span> технологий<br/>-->
<!-- и развитие <span id="targetTitleSpan">в IT</span><br/>--> <!-- и развитие <span id="targetTitleSpan">в IT</span><br/>-->
</h1> </h1>
</div> </div>
<div class="home__banner" ref="target"> <div class="home__banner" ref="target">
</div> </div>
</div> </div>
<template v-if="true"> <template v-if="true">
<div class="app__content"> <div class="app__content">
@ -27,21 +28,17 @@
<div class="text home__info--item"> <div class="text home__info--item">
IT-RADIO. 2023 IT-RADIO. 2023
<span> <span>
Сегодня IT-сфера развивается настолько быстро, что следить за всеми новинками и изменениями в ней становится все сложнее. Сегодня IT-сфера развивается настолько быстро, что следить за всеми новинками и изменениями в ней становится все сложнее.<br/><br/> Но есть способ всегда быть в курсе последних новостей и событий это IT-радио.
<br/> </span>
<br/> Но есть способ всегда быть в курсе последних новостей и событий это IT-радио.
</span>
</div> </div>
<h2 class="h2 m--border"> <h2 class="h2 m--border">
Открывая новые горизонты в мире технологий Открывая новые горизонты в мире технологий
</h2> </h2>
<div class="text home__info--item m--circle"> <div class="text home__info--item m--circle">
<span> <span>
IT-радио это уникальный проект, который объединяет в себе самых ярких представителей IT-индустрии, а также экспертов из различных областей, чтобы поделиться своими знаниями и опытом с широкой аудиторией. IT-радио это уникальный проект, который объединяет в себе самых ярких представителей IT-индустрии, а также экспертов из различных областей, чтобы поделиться своими знаниями и опытом с широкой аудиторией.<br/><br/>
<br/> Каждое шоу на IT-радио включает в себя актуальные темы, новости, обзоры, интервью с экспертами и многое другое.
<br/> </span>
Каждое шоу на IT-радио включает в себя актуальные темы, новости, обзоры, интервью с экспертами и многое другое.
</span>
</div> </div>
</div> </div>
<div class="home__content"> <div class="home__content">
@ -70,7 +67,8 @@
<div class="home__social--description"> <div class="home__social--description">
<h2 class="h2 m--white">Соц сети</h2> <h2 class="h2 m--white">Соц сети</h2>
<div class="text"> <div class="text">
Следите за обновлениями и новыми постами на IT Radio, чтобы быть в курсе последних новостей и Следите за обновлениями и новыми постами на IT Radio, чтобы быть в курсе последних новостей
и
событий в мире IT, а также следить за анонсами и обновлениями! событий в мире IT, а также следить за анонсами и обновлениями!
</div> </div>
</div> </div>
@ -86,7 +84,7 @@
<blog/> <blog/>
</div> </div>
</template> </template>
</div> </div>
</template> </template>
<script> <script>
@ -97,39 +95,39 @@ import RubricBlock from "components/rubric-block.vue";
import Blog from "components/blog.vue"; import Blog from "components/blog.vue";
export default { export default {
name: 'home', name: 'home',
components: {Blog, RubricBlock, Team}, components: {Blog, RubricBlock, Team},
created() { created() {
}, },
mounted() { mounted() {
this.initScene(); this.initScene();
}, },
methods: { methods: {
initScene() { initScene() {
gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollTrigger);
gsap.to(this.$refs.target, { gsap.to(this.$refs.target, {
scale: 1, scale: 1,
scrollTrigger: { scrollTrigger: {
trigger: this.$refs.targetWrapper, trigger: this.$refs.targetWrapper,
scrub: true, scrub: true,
start: 0, start: 0,
end: 600, end: 600,
pin: true, pin: true,
}, },
}, },
); );
gsap.to(this.$refs.targetTitle, { gsap.to(this.$refs.targetTitle, {
color: 'transparent', color: 'transparent',
backgroundImage: 'linear-gradient(91.17deg, #C6F1F7 -4.01%, #F983E9 36.14%, #B877FF 77.44%, #C2E9CD 106.11%)', backgroundImage: 'linear-gradient(91.17deg, #C6F1F7 -4.01%, #F983E9 36.14%, #B877FF 77.44%, #C2E9CD 106.11%)',
scrollTrigger: { scrollTrigger: {
trigger: this.$refs.targetWrapper, trigger: this.$refs.targetWrapper,
scrub: true, scrub: true,
start: 0, start: 0,
end: 600, end: 600,
}, },
}, },
); );
} }
} }
} }
</script> </script>

View File

@ -6,7 +6,7 @@
{ name: 'Личный кабинет', route: { name: 'profile' } }, { name: 'Личный кабинет', route: { name: 'profile' } },
]" ]"
/> />
<h1 class="h2 profile__title">Имя фамилия</h1> <h1 class="h2 profile__title">{{ user.email }}</h1>
<button class="button m--text-link">Редактировать профиль</button> <button class="button m--text-link">Редактировать профиль</button>
<div class="profile__tabs tabs m--btns"> <div class="profile__tabs tabs m--btns">
<button <button
@ -22,10 +22,11 @@
<template v-if="currentTabsItem==='music'"> <template v-if="currentTabsItem==='music'">
<template v-if="showLoader"> <template v-if="showLoader">
<div class="loader"> <div class="loader">
<div class="spinner" /> Загрузка данных <div class="spinner"/>
Загрузка данных
</div> </div>
</template> </template>
<SongList v-else :songList="songList"/> <SongList v-else :songList="userFavorite.songs"/>
</template> </template>
</div> </div>
</template> </template>
@ -55,8 +56,16 @@ export default {
name: 'playlists' name: 'playlists'
}, },
], ],
songList:[], songList: [],
showLoader:true, showLoader: true,
}
},
computed: {
user() {
return this.$store.state.user;
},
userFavorite(){
return this.$store.state.userFavorite
} }
}, },
watch: { watch: {
@ -75,12 +84,12 @@ export default {
this.getSongList(); this.getSongList();
}, },
methods: { methods: {
getSongList(){ getSongList() {
this.showLoader = true; this.showLoader = true;
app.getFavoriteList().then(res=>{ app.getFavoriteList().then(res => {
this.showLoader = false; this.showLoader = false;
this.songList = res; this.$store.dispatch('setUserFavorite', {songs: res})
}).catch(err=>{ }).catch(err => {
this.showLoader = false; this.showLoader = false;
console.error(err) console.error(err)
}) })