Skip to content

Commit

Permalink
Merge pull request #61 from Hyperskill-Community/card-detail-page
Browse files Browse the repository at this point in the history
  • Loading branch information
Averageasd authored Feb 3, 2024
2 parents 95219b5 + 7396a25 commit 29210e0
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .dev/http-client/get-cards.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###
# @no-cookie-jar
GET {{backendUrl}}/api/cards?categoryId=65a5677d296bf15455f0b867&page=0
GET {{backendUrl}}/api/cards?categoryId=65a55ebf7adc427432d46fe1&page=0
Authorization: Bearer {{$auth.token("auth-id")}}

73 changes: 73 additions & 0 deletions frontend/src/feature/cards/components/CardDetailsComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<v-container fluid>
<v-row justify="center">
<v-col cols="12" md="8" lg="6">
<v-card
class="pa-2 ma-2 mx-auto d-flex flex-column justify-space-between">
<v-card-title>
{{ card.title }}
</v-card-title>
<v-card-subtitle>
<v-list class="ma-0 pa-0 d-flex flex-row flex-wrap">
<v-list-item
v-for="tag in card.tags"
:title="tag as string"
>
</v-list-item>
</v-list>
</v-card-subtitle>
<v-card-text>
{{ card.question }}
<v-container class="pa-0 mt-2">
<v-container class="pa-0">
Choices:
</v-container>
<v-list class="pa-0 d-flex flex-column flex-wrap">
<v-list-item
v-for="(option, index) in card.options"
:title="(index + 1) + './' + option as string"
>
</v-list-item>
</v-list>
</v-container>
<v-container class="pa-0 mt-2">
Answer: {{ card.correctOption }}
</v-container>

</v-card-text>
<v-container>
<v-card-actions class="pa-0 ma-0">
<edit-mdi-button>Edit</edit-mdi-button>
<delete-mdi-button>Delete</delete-mdi-button>
</v-card-actions>
</v-container>
</v-card>
</v-col>
</v-row>

</v-container>
</template>

<script setup lang="ts">
import EditMdiButton from "@/shared/components/EditMdiButton.vue";
import DeleteMdiButton from "@/shared/components/DeleteMdiButton.vue";
const card = defineProps({
id: String,
title: String,
question: String,
correctOption: String,
tags: Array as () => String[],
options: Array as () => String[]
});
</script>

<style scoped lang="scss">
.v-card {
background-color: #f0f8ff;
}
</style>
21 changes: 19 additions & 2 deletions frontend/src/feature/cards/composables/useCardsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const useCardsService = () => {
}
}

const getCards = async (categoryId: string, page: number, errorResult: string = 'throw') : Promise<Card[]> => {
const getCards = async (categoryId: string, page: number, errorResult: string = 'throw'): Promise<Card[]> => {
const url = `${apiUrl}cards?categoryId=${categoryId}&page=${page}`;

try {
Expand All @@ -44,7 +44,23 @@ const useCardsService = () => {
}
}

const getCardCount = async (categoryId: string, errorResult: string = 'throw') => {
const getCardById = async (cardId: string, categoryId: string, errorResult: string = 'throw'): Promise<Card> => {
const url = apiUrl + 'cards/' + cardId + '?categoryId=' + categoryId;
try {
const response = await apiClient.get(url);
if (response.status !== 200) {
throw new Error(`Error status code ${response.status}!`);
} else {
return (response.data as Card);
}
} catch (error: any) {
errorResult === 'throw' ? useErrorService().handleAndThrow(error)
: useErrorService().handleAndNotify('custom error', 'custom message');
return {} as Card;
}
}

const getCardCount = async (categoryId: string, errorResult: string = 'throw') => {
const url = apiUrl + 'cards/count?categoryId=' + categoryId;

try {
Expand All @@ -64,6 +80,7 @@ const useCardsService = () => {
return {
postNewUser,
getCards,
getCardById,
getCardCount
}
}
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/feature/cards/model/card.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export type Card = {
id: string,
title: string,
correctOption: string,
question: string,
options: string[],
tags: string[],
}
// "id": "65a5677d296bf15455f0b868",
Expand Down
50 changes: 26 additions & 24 deletions frontend/src/feature/cards/pages/CardDetailsPage.vue
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
<template>
<v-container>
<h2 class="text-center">Card Details Page for card with Id: {{ props.id }}</h2>
<v-card class="pa-2 ma-2 mx-auto d-flex flex-column justify-space-between" max-width="500px" min-height="300px"
color="#f0f8ff">
<v-card-title class="text-center text-sm-h3">
Card '{{ props.id }}'
</v-card-title>
<v-card-subtitle>
sport, math, programming
</v-card-subtitle>
<v-card-text>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aenean commodo ligula eget dolor. Aenean massa.
Cum sociis natoque penatibus et
</v-card-text>
<v-container>
<v-card-actions>
<v-btn class="bg-blue-accent-1 font-weight-medium">Edit</v-btn>
<v-btn class="bg-blue-accent-1 font-weight-medium">Delete</v-btn>
</v-card-actions>
</v-container>
</v-card>
<div v-if="!Object.keys(card).length">
<p>no card with {{id}}</p>
</div>
<div v-else>
<CardDetailsComponent v-bind="card"></CardDetailsComponent>
</div>

</v-container>
</template>


<script setup lang="ts">
import CardDetailsComponent from "@/feature/cards/components/CardDetailsComponent.vue";
import {ref} from "vue";
import {Card} from "@/feature/cards/model/card";
import useCardsService from "@/feature/cards/composables/useCardsService";
const CATEGORY_ID = "65b7f591f51c4b418123768e";
const props = defineProps({
id: String
id: String,
})
</script>
<style scoped>
const card = ref<Card>(
{} as Card
);
async function fetchCardWithId() {
card.value = await useCardsService().getCardById(props.id!, CATEGORY_ID);
}
fetchCardWithId();
</script>
<style scoped>
</style>

0 comments on commit 29210e0

Please sign in to comment.