Skip to content

Commit a6bdc39

Browse files
committed
feat (frontend): Update Status Cards
1 parent a83fa2c commit a6bdc39

File tree

14 files changed

+201
-102
lines changed

14 files changed

+201
-102
lines changed

frontend/src/App.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import { RouterView, RouterLink } from 'vue-router'
88
<div class="mx-auto flex flex-col gap-8 items-center">
99
<div class="text-center flex flex-col gap-4">
1010
<router-link to="/">
11-
<h1 class="text-4xl font-bold text-foreground">My Chess Style</h1></router-link
11+
<h1 class="text-4xl font-bold text-foreground hover:underline hover:decoration-sky-400">
12+
My Chess Style
13+
</h1></router-link
1214
>
1315
<p class="text-xl text-muted-foreground">
1416
Analyze your chess games and discover your playing style

frontend/src/assets/main.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
@theme {
77
--color-muted: var(--color-gray-100);
8+
--color-muted: hsl(210 40% 96.1%);
89
--color-muted-foreground: hsl(215.4 16.3% 46.9%);
910
}
1011

frontend/src/components/HomeCardWithOptions.vue

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { ref, type Ref } from 'vue'
33
import { useFetch } from '@vueuse/core'
44
import { useUIStore } from '@/stores/ui'
55
import type { PlatformOptions } from '@/types'
6+
import { useRouter } from 'vue-router'
7+
8+
const router = useRouter()
69
710
const uploadFile = ref()
811
const pgnUsername: Ref<string> = ref('')
@@ -24,51 +27,56 @@ async function uploadPGNFile() {
2427
formData.append('pgn_file', uploadFile.value.files[0])
2528
formData.append('usernames', pgnUsername.value)
2629
formData.append('include_roast', includeRoast.value)
27-
const { data, pending, error, refresh } = await useFetch('/server/pgn/upload', {
28-
method: 'POST',
29-
body: formData,
30-
}).json()
31-
if (error.value) {
32-
toastClass.value = ui.showMessage('error', 'Error', error.value)
33-
} else {
34-
await navigator.clipboard.writeText(data.value.status_id)
35-
toastClass.value = ui.showMessage(
36-
'success',
37-
'Upload successful',
38-
`Tracking ID copied to clipboard!`,
39-
)
30+
try {
31+
const response = await fetch('/server/pgn/upload', {
32+
method: 'POST',
33+
body: formData,
34+
})
35+
const data = await response.json()
36+
if (!response.ok) {
37+
ui.showMessage('error', 'Error', data.message)
38+
} else {
39+
await navigator.clipboard.writeText(data.status_id)
40+
toastClass.value = ui.showMessage(
41+
'success',
42+
'Upload successful',
43+
`Tracking ID copied to clipboard!`,
44+
)
45+
}
46+
} catch (error) {
47+
ui.showMessage('error', 'Error', error)
4048
}
4149
}
4250
4351
async function uploadPlatformUsernames() {
44-
const { data, pending, error, refresh } = await useFetch('/server/pgn/external_user/')
45-
.post({
46-
username: platformUsername.value,
47-
platform: externalPlatform.value.code,
48-
include_roast: includeRoast.value,
52+
try {
53+
const response = await fetch('/server/pgn/external_user/', {
54+
method: 'POST',
55+
headers: { 'Content-Type': 'application/json' },
56+
body: JSON.stringify({
57+
username: platformUsername.value,
58+
platform: externalPlatform.value.code,
59+
include_roast: includeRoast.value,
60+
}),
4961
})
50-
.json()
51-
if (error.value) {
52-
toastClass.value = ui.showMessage('error', 'Error', error.value)
53-
} else {
54-
await navigator.clipboard.writeText(data.value.status_id)
55-
toastClass.value = ui.showMessage(
56-
'success',
57-
'Upload successful',
58-
`Tracking ID copied to clipboard!`,
59-
)
62+
const data = await response.json()
63+
if (!response.ok) {
64+
ui.showMessage('error', 'Error', data.message)
65+
} else {
66+
await navigator.clipboard.writeText(data.status_id)
67+
toastClass.value = ui.showMessage(
68+
'success',
69+
'Upload successful',
70+
`Tracking ID copied to clipboard!`,
71+
)
72+
}
73+
} catch (error) {
74+
ui.showMessage('error', 'Error', error)
6075
}
6176
}
6277
6378
async function checkStatusByTransactionID() {
64-
const { data, pending, error, refresh } = await useFetch(
65-
`/server/analysis/status/${trackingID.value}`,
66-
).json()
67-
if (error.value) {
68-
toastClass.value = ui.showMessage('error', 'Error', error.value)
69-
} else {
70-
toastClass.value = ui.showMessage('success', 'Upload successful', `Tracking ID: ${data.value}`)
71-
}
79+
router.push(`/status/${trackingID.value}`)
7280
}
7381
</script>
7482

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
import { type FileUploadData } from '@/types'
3+
const props = defineProps<{
4+
informationObject: FileUploadData
5+
}>()
6+
const sources = ['Chess.com', 'Lichess', 'PGN file']
7+
const source = sources[props.informationObject.source - 1]
8+
</script>
9+
<template>
10+
<div>
11+
<Card>
12+
<template #title>Basic Information</template>
13+
<template #content>
14+
<div class="grid grid-cols-2 gap-7">
15+
<div class="text-center p-4 bg-muted rounded-lg">
16+
<div class="text-xl font-black text-black">
17+
{{ props.informationObject.usernames }}
18+
</div>
19+
<div class="text-sm text-muted-foreground">Username</div>
20+
</div>
21+
<div class="text-center p-4 bg-muted rounded-lg">
22+
<div class="text-xl font-black text-black">
23+
{{ source }}
24+
</div>
25+
<div class="text-sm text-muted-foreground">Source</div>
26+
</div>
27+
</div>
28+
</template>
29+
</Card>
30+
</div>
31+
</template>

frontend/src/components/StatusCardWithGamesAnalysis.vue

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const props = defineProps<{
66
</script>
77
<template>
88
<div>
9-
<Card>
9+
<Card v-if="gameObjects.count">
1010
<template #title>Preliminary Game Analysis</template>
1111
<template #content>
1212
<div class="grid grid-cols-1 gap-4">
@@ -71,6 +71,35 @@ const props = defineProps<{
7171
</div>
7272
</div>
7373
</div>
74+
<div class="mt-4">
75+
<h4 class="font-black text-xl my-8">Top Openings</h4>
76+
<div class="flex flex-col gap-3">
77+
<div
78+
v-for="([opening, data], idx) in props.gameObjects.openings"
79+
:key="idx"
80+
class="flex items-center justify-between p-3 bg-muted rounded-lg"
81+
>
82+
<div class="flex-1">
83+
<div class="font-medium text-sm">{{ opening }}</div>
84+
<div class="text-xs text-muted-foreground">
85+
ECO: {{ data.eco_codes.join(', ') }}
86+
</div>
87+
</div>
88+
<div class="text-right">
89+
<div class="text-lg font-bold text-primary">{{ data.total }}</div>
90+
<div class="text-xs text-muted-foreground">games</div>
91+
</div>
92+
</div>
93+
</div>
94+
</div>
95+
</div>
96+
</template>
97+
</Card>
98+
<Card v-else>
99+
<template #title>Preliminary Game Analysis</template>
100+
<template #content>
101+
<div class="grid grid-cols-1 gap-4">
102+
<h2 class="text-primary">No games played by user</h2>
74103
</div>
75104
</template>
76105
</Card>

frontend/src/components/StatusCardWithRoast.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import { type RoastingUserData } from '@/types'
33
const props = defineProps<{
4-
roastData: RoastingUserData
4+
roastObjects: RoastingUserData
55
}>()
66
</script>
77
<template>
@@ -15,20 +15,20 @@ const props = defineProps<{
1515
<div class="grid grid-cols-1 gap-6">
1616
<div class="p-4 bg-red-50 border-l-4 border-red-500 rounded-lg">
1717
<h4 class="font-semibold text-red-800 mb-2">The Roast</h4>
18-
<p class="text-red-700 whitespace-pre-line">{{ props.roastData.roast }}</p>
18+
<p class="text-red-700 whitespace-pre-line">{{ props.roastObjects.roast }}</p>
1919
</div>
2020

2121
<div class="p-4 bg-blue-50 border-l-4 border-blue-500 rounded-lg">
2222
<h4 class="font-semibold text-blue-800 mb-2">Encouragement</h4>
2323
<p class="text-blue-700 whitespace-pre-line">
24-
{{ props.roastData.encouragement }}
24+
{{ props.roastObjects.encouragement }}
2525
</p>
2626
</div>
2727

2828
<div class="p-4 bg-green-50 border-l-4 border-green-500 rounded-lg">
2929
<h4 class="font-semibold text-green-800 mb-3">Tips for Improvement</h4>
3030
<p class="text-green-600 whitespace-pre-line">
31-
{{ props.roastData.tip }}
31+
{{ props.roastObjects.tip }}
3232
</p>
3333
</div>
3434
</div>

frontend/src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Toast from 'primevue/toast'
2323
import ToastService from 'primevue/toastservice'
2424
import Select from 'primevue/select'
2525
import ProgressBar from 'primevue/progressbar'
26+
import Skeleton from 'primevue/skeleton'
2627

2728
const app = createApp(App)
2829

@@ -40,6 +41,7 @@ app.component('FileUpload', FileUpload)
4041
app.component('Toast', Toast)
4142
app.component('Select', Select)
4243
app.component('ProgressBar', ProgressBar)
44+
app.component('Skeleton', Skeleton)
4345

4446
app.use(createPinia())
4547
app.use(router)

frontend/src/stores/counter.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

frontend/src/stores/ui.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import type { NotificationTheme } from '@/types'
22
import { defineStore } from 'pinia'
33
import { useToast } from 'primevue'
4-
import { ref, type Ref } from 'vue'
4+
5+
const toastTheme = new Map<NotificationTheme, string>([
6+
['error', 'bg-red-500 text-white'],
7+
['success', 'bg-green-600 text-white'],
8+
['secondary', 'bg-slate-200 text-black'],
9+
['info', 'bg-sky-500 text-white'],
10+
['warn', 'bg-orange-600 text-white'],
11+
['contrast', 'bg-slate-900 text-white'],
12+
])
513

614
export const useUIStore = defineStore('ui', () => {
715
const toast = useToast()
816
function showMessage(severity: NotificationTheme, summary: string, detail: string): string {
9-
const toastTheme = new Map<NotificationTheme, string>([
10-
['error', 'bg-red-500 text-white'],
11-
['success', 'bg-green-600 text-white'],
12-
['secondary', 'bg-slate-200 text-black'],
13-
['info', 'bg-sky-500 text-white'],
14-
['warn', 'bg-orange-600 text-white'],
15-
['contrast', 'bg-slate-900 text-white'],
16-
])
1717
const toastThemeClass: string = toastTheme.get(severity) ?? 'bg-green-600 text-white'
1818
toast.add({
1919
severity: severity,

frontend/src/types/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@ export interface RoastingUserData {
2323
roast: string
2424
encouragement: string
2525
}
26+
export interface FileUploadData {
27+
source?: number
28+
status?: string
29+
usernames?: string
30+
}
2631
export interface AnalysisDataResult {
27-
file_upload?: string
32+
file_upload?: FileUploadData
2833
game?: GameData
2934
roasting_user?: RoastingUserData
30-
chess_style?: Object
35+
chess_style?: object
3136
}
3237
export interface AnalysisData {
3338
result?: AnalysisDataResult

0 commit comments

Comments
 (0)