mirror of
https://github.com/Dannecron/ich-lerne-deutsch.git
synced 2025-12-25 12:52:35 +03:00
Components refactoring: drop second layout for article.
Move components info subfolders. Combine detail components for list and for page. Improve helpers, add declOfNum function.
This commit is contained in:
85
src/components/Article/Details.vue
Normal file
85
src/components/Article/Details.vue
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<v-card color="info" class="white--text">
|
||||||
|
<v-container fluid>
|
||||||
|
<v-layout row>
|
||||||
|
<v-flex xs4 md3>
|
||||||
|
<v-img
|
||||||
|
src="https://images-na.ssl-images-amazon.com/images/I/51U6bQbA8oL._SY346_.jpg"
|
||||||
|
v-bind:height="expandDetails ? '150px' : '100px'"
|
||||||
|
>
|
||||||
|
</v-img>
|
||||||
|
<youtube-button class="hidden-sm-and-down"></youtube-button>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs8 md9>
|
||||||
|
<v-card-title>
|
||||||
|
<div :class="{
|
||||||
|
'subheading': $vuetify.breakpoint.smAndDown,
|
||||||
|
'headline': $vuetify.breakpoint.mdAndUp,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ article.title }}
|
||||||
|
</div>
|
||||||
|
<youtube-button class="hidden-md-and-up"></youtube-button>
|
||||||
|
</v-card-title>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-layout row wrap>
|
||||||
|
<v-flex xs12 md8 order-md2>
|
||||||
|
<div>{{ article.description }}</div>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 md4 order-md1>
|
||||||
|
<div>Уровень: {{ getArticleLevel(article.level) }} {{ partsDescription }}</div>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-layout row>
|
||||||
|
<v-flex xs12>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-rating v-model="article.rating" color="yellow" readonly dense half-increments></v-rating>
|
||||||
|
<div class="ml-1">
|
||||||
|
<span>{{ article.rating }}</span>
|
||||||
|
<span>({{ article.ratingsCount }})</span>
|
||||||
|
</div>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn v-if="!expandDetails" class="primary" flat :to="{ name: 'article', params: { articleId: article.id } }">
|
||||||
|
Открыть
|
||||||
|
</v-btn>
|
||||||
|
<v-btn v-if="expandDetails" class="primary" flat>Добавить</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import YoutubeButton from '@/components/Article/YoutubeButton';
|
||||||
|
import { getArticleLevel, declOfNum } from '@/helpers';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
article: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
expandDetails: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
partsDescription() {
|
||||||
|
const partsCount = this.article.parts.length;
|
||||||
|
const partsCountWord = declOfNum(partsCount, ['часть', 'части', 'частей']);
|
||||||
|
return `${partsCount} ${partsCountWord}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getArticleLevel: getArticleLevel,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
YoutubeButton,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
11
src/components/Article/YoutubeButton.vue
Normal file
11
src/components/Article/YoutubeButton.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<v-btn flat color="white">
|
||||||
|
<v-icon left>visibility</v-icon>
|
||||||
|
Youtube
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-card color="info" class="white--text">
|
|
||||||
<v-container fluid>
|
|
||||||
<!-- desktop layout -->
|
|
||||||
<v-layout row class="hidden-sm-and-down">
|
|
||||||
<v-flex md3>
|
|
||||||
<v-img
|
|
||||||
src="https://images-na.ssl-images-amazon.com/images/I/51U6bQbA8oL._SY346_.jpg"
|
|
||||||
height="150px"
|
|
||||||
>
|
|
||||||
</v-img>
|
|
||||||
<div class="text-xs-center">
|
|
||||||
<v-btn flat color="white">
|
|
||||||
<v-icon left>visibility</v-icon>
|
|
||||||
Youtube
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-flex>
|
|
||||||
<v-flex md9>
|
|
||||||
<v-card-title>
|
|
||||||
<div>
|
|
||||||
<div class="headline">{{ article.title }}</div>
|
|
||||||
<div>{{ article.description }}</div>
|
|
||||||
<v-divider class="white"></v-divider>
|
|
||||||
<div>Уровень: {{ getArticleLevel(article.level) }} {{ article.parts.length }} частей</div>
|
|
||||||
</div>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-rating v-model="article.rating" color="yellow" readonly dense half-increments></v-rating>
|
|
||||||
<div class="ml-1">
|
|
||||||
<span>{{ article.rating }}</span>
|
|
||||||
<span>({{ article.ratingsCount }})</span>
|
|
||||||
</div>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn class="primary" flat>Добавить</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<!-- tablet and mobile layout -->
|
|
||||||
<div class="hidden-md-and-up">
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs4>
|
|
||||||
<v-img
|
|
||||||
src="https://images-na.ssl-images-amazon.com/images/I/51U6bQbA8oL._SY346_.jpg"
|
|
||||||
height="100px"
|
|
||||||
>
|
|
||||||
</v-img>
|
|
||||||
</v-flex>
|
|
||||||
<v-flex xs8>
|
|
||||||
<v-card-title>
|
|
||||||
<h4>{{ article.title }}</h4>
|
|
||||||
<v-btn flat color="white">
|
|
||||||
<v-icon left>visibility</v-icon>
|
|
||||||
Youtube
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<div>{{ article.description }}</div>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<div>Уровень: {{ getArticleLevel(article.level) }} {{ article.parts.length }} частей</div>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-rating v-model="article.rating" color="yellow" readonly dense half-increments></v-rating>
|
|
||||||
<div class="ml-1">
|
|
||||||
<span>{{ article.rating }}</span>
|
|
||||||
<span>({{ article.ratingsCount }})</span>
|
|
||||||
</div>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn class="primary" flat>Добавить</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import getArticleLevel from '@/helpers/article';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
article: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getArticleLevel: getArticleLevel,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ListItem from '@/components/ArticlesListItem';
|
import ListItem from '@/components/Article/Details';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-card color="info" class="white--text">
|
|
||||||
<v-container fluid>
|
|
||||||
<!-- desktop layout -->
|
|
||||||
<v-layout row class="hidden-sm-and-down">
|
|
||||||
<v-flex md3>
|
|
||||||
<v-img
|
|
||||||
src="https://images-na.ssl-images-amazon.com/images/I/51U6bQbA8oL._SY346_.jpg"
|
|
||||||
height="100px"
|
|
||||||
>
|
|
||||||
</v-img>
|
|
||||||
<div class="text-xs-center">
|
|
||||||
<v-btn flat color="white">
|
|
||||||
<v-icon left>visibility</v-icon>
|
|
||||||
Youtube
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-flex>
|
|
||||||
<v-flex md9>
|
|
||||||
<v-card-title>
|
|
||||||
<div>
|
|
||||||
<div class="headline">{{ article.title }}</div>
|
|
||||||
<div>{{ article.description }}</div>
|
|
||||||
<v-divider class="white"></v-divider>
|
|
||||||
<div>Уровень: {{ getArticleLevel(article.level) }} {{ article.parts.length }} частей</div>
|
|
||||||
</div>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-rating v-model="article.rating" color="yellow" readonly dense half-increments></v-rating>
|
|
||||||
<div class="ml-1">
|
|
||||||
<span>{{ article.rating }}</span>
|
|
||||||
<span>({{ article.ratingsCount }})</span>
|
|
||||||
</div>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn class="primary" flat :to="{ name: 'article', params: { articleId: article.id } }">
|
|
||||||
Открыть
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<!-- tablet and mobile layout -->
|
|
||||||
<div class="hidden-md-and-up">
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs4>
|
|
||||||
<v-img
|
|
||||||
src="https://images-na.ssl-images-amazon.com/images/I/51U6bQbA8oL._SY346_.jpg"
|
|
||||||
height="100px"
|
|
||||||
>
|
|
||||||
</v-img>
|
|
||||||
</v-flex>
|
|
||||||
<v-flex xs8>
|
|
||||||
<v-card-title>
|
|
||||||
<h4>{{ article.title }}</h4>
|
|
||||||
<v-btn flat color="white">
|
|
||||||
<v-icon left>visibility</v-icon>
|
|
||||||
Youtube
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<div>{{ article.description }}</div>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<div>Уровень: {{ getArticleLevel(article.level) }} {{ article.parts.length }} частей</div>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
|
|
||||||
<v-layout row>
|
|
||||||
<v-flex xs12>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-rating v-model="article.rating" color="yellow" readonly dense half-increments></v-rating>
|
|
||||||
<div class="ml-1">
|
|
||||||
<span>{{ article.rating }}</span>
|
|
||||||
<span>({{ article.ratingsCount }})</span>
|
|
||||||
</div>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn class="primary" flat :to="{ name: 'article', params: { articleId: article.id } }">
|
|
||||||
Открыть
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import getArticleLevel from '@/helpers/article';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
article: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getArticleLevel: getArticleLevel,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,3 +1 @@
|
|||||||
const getArticleLevel = levels => levels.join('/');
|
export const getArticleLevel = levels => levels.join('/');
|
||||||
|
|
||||||
export default getArticleLevel;
|
|
||||||
|
|||||||
2
src/helpers/index.js
Normal file
2
src/helpers/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from '@/helpers/article';
|
||||||
|
export * from '@/helpers/utils';
|
||||||
4
src/helpers/utils.js
Normal file
4
src/helpers/utils.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export const declOfNum = (number, titles) => {
|
||||||
|
const cases = [2, 0, 1, 1, 1, 2];
|
||||||
|
return titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
|
||||||
|
};
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<v-container grid-list-md v-if="article">
|
<v-container grid-list-md v-if="article">
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xs12 xs10 offset-sm1>
|
<v-flex xs12 xs10 offset-sm1>
|
||||||
<article-details :article="article"></article-details>
|
<article-details :article="article" :expandDetails="true"></article-details>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 xs10 offset-sm1 v-for="part in article.parts" :key="part.id">
|
<v-flex xs12 xs10 offset-sm1 v-for="part in article.parts" :key="part.id">
|
||||||
<article-parts-list-item :part="part" :articleId="article.id"></article-parts-list-item>
|
<article-parts-list-item :part="part" :articleId="article.id"></article-parts-list-item>
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ArticleDetails from '@/components/ArticleDetails';
|
import ArticleDetails from '@/components/Article/Details';
|
||||||
import ArticlePartsListItem from '@/components/ArticlePartsListItem';
|
import ArticlePartsListItem from '@/components/Article/Part/ListItem';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
Reference in New Issue
Block a user