Skip to content
This repository was archived by the owner on Dec 8, 2022. It is now read-only.

Commit b4b4176

Browse files
make VoteLeaderboardSearch component, update Ballot to accomodate, begin making new route for leaderboard after vote has ended
1 parent 11eb5dc commit b4b4176

File tree

3 files changed

+253
-217
lines changed

3 files changed

+253
-217
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<template>
2+
<v-container>
3+
<v-row>
4+
<v-col>
5+
<h2 class="ballot-header mt-8 mb-8">
6+
<slot name="header">Vote Now</slot>
7+
</h2>
8+
<SearchBar v-model="searchText" />
9+
10+
<div style="color:#0d1d41" class="mb-6 mt-4 text-center">
11+
<slot name="content">
12+
Behold, the final contestants who have completed 21 coding
13+
challenges, a noble and righteous accomplishment! Now, they have
14+
defeated the mighty dragon in the end boss level and qualified for
15+
the grand prize, but they need your help!
16+
<br />
17+
<br />
18+
<b>
19+
View the contestants and their code, then Vote for the winner of
20+
our first ever kids coding challenge, The Dragon Quest. Their fate
21+
is in your hands.
22+
</b>
23+
</slot>
24+
</div>
25+
26+
<h2
27+
v-if="!isLoading && pageData.items.length === 0 && searchText !== ''"
28+
>
29+
Could not find any results for "{{ searchText }}"
30+
</h2>
31+
<h2 v-else-if="searchText !== ''">
32+
Showing results for "{{ searchText }}"
33+
</h2>
34+
</v-col>
35+
</v-row>
36+
<v-row justify="center" v-if="isLoading">
37+
<v-col class="text-center">
38+
<v-progress-circular
39+
class="mt-6"
40+
color="cwhqBlue"
41+
size="100"
42+
width="10"
43+
indeterminate
44+
/>
45+
<h2 class="mt-6">
46+
Loading Results <small><br />Please Wait</small>
47+
</h2>
48+
</v-col>
49+
</v-row>
50+
<v-row v-else-if="pageData.items === 0">
51+
No results were found for "{{ searchText }}"
52+
</v-row>
53+
<v-row justify="center" v-else>
54+
<BallotCard
55+
v-for="(item, i) in pageData.items"
56+
:key="i"
57+
v-bind="item"
58+
@click="showCode(item)"
59+
/>
60+
</v-row>
61+
<v-row justify="center" v-if="pageData.totalPages > 1 && !isLoading">
62+
<v-pagination
63+
v-model="pageData.page"
64+
:length="pageData.totalPages"
65+
circle
66+
></v-pagination>
67+
</v-row>
68+
<CodeModal v-bind="this.item" v-model="showModal" />
69+
</v-container>
70+
</template>
71+
72+
<script>
73+
import Vue from "vue";
74+
import { voting } from "@/api";
75+
import BallotCard from "@/views/Voting/BallotCard";
76+
import CodeModal from "@/views/Voting/CodeModal";
77+
import SearchBar from "@/views/Voting/SearchBar";
78+
export default {
79+
name: "VoteLeaderboardSearch",
80+
components: {
81+
BallotCard,
82+
CodeModal,
83+
SearchBar
84+
},
85+
data() {
86+
return {
87+
totalEntries: "",
88+
requestIndex: 0,
89+
requestCount: 0,
90+
showModal: false,
91+
searchText: "",
92+
item: null,
93+
per: 50,
94+
pageData: {
95+
hasNext: false,
96+
hasPrev: false,
97+
nextNum: false,
98+
page: -1,
99+
items: [],
100+
prevNum: null,
101+
totalItems: 0,
102+
totalPages: 0
103+
}
104+
};
105+
},
106+
methods: {
107+
showCode(item) {
108+
this.item = item;
109+
this.showModal = true;
110+
},
111+
async setResult(result) {
112+
await new Promise(resolve =>
113+
setTimeout(async () => {
114+
for (const [key, value] of Object.entries(result)) {
115+
Vue.set(this.pageData, key, value);
116+
}
117+
await this.updateQueryParams();
118+
resolve();
119+
}, 1000)
120+
);
121+
},
122+
async search() {
123+
if (this.searchText === "") {
124+
return this.loadPage();
125+
}
126+
this.pageData.page = 1;
127+
this.requestIndex++;
128+
this.requestCount++;
129+
const requestIndex = this.requestIndex;
130+
const searchText = this.searchText;
131+
try {
132+
const results = await voting.search(
133+
this.searchText,
134+
this.pageData.page,
135+
this.per
136+
);
137+
if (
138+
this.searchText === searchText &&
139+
this.requestIndex === requestIndex
140+
) {
141+
await this.setResult(results);
142+
}
143+
} catch (err) {
144+
// eslint-disable-next-line no-console
145+
if (err.status === 404) {
146+
this.pageData.page = 1;
147+
await this.search();
148+
} else {
149+
// for testing
150+
// TODO: remove if later
151+
if (this.$router.history._startLocation !== "/testing/vote") {
152+
this.$router.push({ name: "redirect" });
153+
}
154+
}
155+
}
156+
this.requestCount--;
157+
},
158+
async loadPage() {
159+
this.requestCount++;
160+
try {
161+
const results = await voting.getBallot(this.pageData.page, this.per);
162+
await this.setResult(results);
163+
} catch (err) {
164+
if (err.status === 404) {
165+
this.pageData.page = 1;
166+
await this.loadPage();
167+
} else {
168+
// for testing
169+
// TODO: remove if later
170+
if (this.$router.history._startLocation !== "/testing/vote") {
171+
this.$router.push({ name: "redirect" });
172+
}
173+
}
174+
}
175+
this.requestCount--;
176+
},
177+
async updateQueryParams() {
178+
try {
179+
const query = {
180+
page: this.pageData.page
181+
};
182+
if (this.searchText !== "") {
183+
query.search = encodeURIComponent(this.searchText);
184+
}
185+
await this.$router.replace({ name: this.$route.name, query });
186+
} catch (err) {
187+
// do nothing.
188+
}
189+
},
190+
async refresh() {
191+
if (this.searchText === "") {
192+
this.loadPage();
193+
} else {
194+
this.search();
195+
}
196+
}
197+
},
198+
computed: {
199+
isLoading() {
200+
return this.requestCount > 0;
201+
}
202+
},
203+
watch: {
204+
searchText() {
205+
this.search();
206+
},
207+
["pageData.page"]() {
208+
this.refresh();
209+
},
210+
["$route.query.page"](val) {
211+
const page = parseInt(val);
212+
if (this.pageData.page === page) {
213+
return;
214+
}
215+
this.pageData.page = page;
216+
this.refresh();
217+
}
218+
},
219+
async mounted() {
220+
this.searchText =
221+
this.$route.query.search === undefined ? "" : this.$route.query.search;
222+
this.pageData.page =
223+
this.$route.query.page === undefined
224+
? 1
225+
: parseInt(this.$route.query.page);
226+
}
227+
};
228+
</script>
229+
230+
<style></style>

0 commit comments

Comments
 (0)