Skip to content

Commit

Permalink
fix: solution details (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
thezzisu authored Jan 22, 2024
1 parent 273cb3e commit 2371928
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .yarn/versions/69848106.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
releases:
"@aoi-js/frontend": patch
"@aoi-js/server": patch
2 changes: 1 addition & 1 deletion apps/frontend/src/components/solution/SolutionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PrincipalProfile :principal-id="item.userId" />
</template>
<template v-slot:[`item.title`]="{ item }">
<RouterLink :to="rel(item._id)" style="color: primary">
<RouterLink v-if="contestId" :to="rel(item._id)" style="color: primary">
{{ useContestProblemTitle(item.problemId)?.value }}
</RouterLink>
</template>
Expand Down
3 changes: 2 additions & 1 deletion apps/frontend/src/components/solution/SolutionStatusChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const props = defineProps<{
}>()
const knownStatus: Record<string, [string, string]> = {
Accepted: ['mdi-check', 'success']
Accepted: ['mdi-check', 'success'],
Success: ['mdi-check', 'info']
}
const display = computed(() => knownStatus[props.status] ?? ['mdi-circle-outline', ''])
</script>
6 changes: 3 additions & 3 deletions apps/frontend/src/components/solution/SolutionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<!-- <th class="text-center">{{ t('term.hash') }}</th>
<th class="text-center">{{ t('term.runner-label') }}</th> -->
<th class="text-center">{{ t('term.user') }}</th>
<th class="text-center">{{ t('term.title') }}</th>
<th class="text-center" v-if="contestId">{{ t('term.title') }}</th>
<th class="text-center" v-text="t('common.created-at')" />
<th class="text-center" v-if="value.submittedAt" v-text="t('common.submitted-at')" />
</thead>
Expand All @@ -34,7 +34,7 @@
<td class="text-center">
<PrincipalProfile :principal-id="value.userId" />
</td>
<td class="text-center">
<td class="text-center" v-if="contestId">
<code>{{ useContestProblemTitle(value.problemId)?.value }}</code>
</td>
<td class="text-center" v-text="new Date(value.createdAt).toLocaleString()" />
Expand Down Expand Up @@ -98,7 +98,7 @@
<VBtn v-if="showData && !viewFile" :text="t('action.view')" @click="viewFile = true" />
</VCardActions>
<VCardText v-if="showData && viewFile">
<ZipAutoViewer :endpoint="downloadEndpoint" default-file="answer.code" />
<ZipAutoViewer :endpoint="downloadEndpoint" default-file="answer.code" show-metadata />
</VCardText>
<template v-if="showDetails && solution.state.value?.state === 4">
<VDivider />
Expand Down
3 changes: 2 additions & 1 deletion apps/frontend/src/components/utils/zip/ZipAutoViewer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<ZipViewer v-if="zip" :zip="zip" :default-file="props.defaultFile" />
<ZipViewer v-if="zip" :zip="zip" :default-file="defaultFile" :show-metadata="showMetadata" />
</template>

<script setup lang="ts">
Expand All @@ -12,6 +12,7 @@ import ZipViewer from './ZipViewer.vue'
const props = defineProps<{
endpoint: string
defaultFile?: string
showMetadata?: boolean
}>()
const zip = shallowRef<JSZip>()
Expand Down
22 changes: 14 additions & 8 deletions apps/frontend/src/components/utils/zip/ZipViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
<div>
<VList density="compact">
<VListItem
v-for="file in props.zip.files"
:key="file.name"
:title="file.name"
@click="currentFile = file"
v-for="name in files"
:key="zip.files[name].name"
:title="zip.files[name].name"
@click="currentFile = zip.files[name]"
/>
</VList>
</div>
Expand All @@ -27,11 +27,17 @@ import ZipFileViewer from './ZipFileViewer.vue'
const props = defineProps<{
zip: JSZip
defaultFile?: string
showMetadata?: boolean
}>()
const files = computed(() => {
const keys = Object.keys(props.zip.files)
if (props.showMetadata) return keys
return keys.filter((fn) => fn !== '.metadata.json')
})
const showSideBar = computed(() => {
// show iff there are more than one files, excluding .metadata.json
return Object.keys(props.zip.files).filter((fn) => fn !== '.metadata.json').length > 1
return files.value.length > 1
})
const currentFile = shallowRef<JSZip.JSZipObject>()
Expand All @@ -42,8 +48,8 @@ function initialize() {
if (props.defaultFile) {
currentFile.value = props.zip.file(props.defaultFile) ?? undefined
}
if (!currentFile.value && Object.keys(props.zip.files).length == 1) {
currentFile.value = props.zip.files[Object.keys(props.zip.files)[0]]
if (!currentFile.value && !showSideBar.value) {
currentFile.value = props.zip.files[files.value[0]]
}
}
initialize()
Expand Down
12 changes: 7 additions & 5 deletions apps/frontend/src/pages/auth/login/iaaa.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@

<script setup lang="ts">
import { useAsyncTask } from '@/utils/async'
import { http, login, prettyHTTPError } from '@/utils/http'
import { http, prettyHTTPError } from '@/utils/http'
import { onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { getToken } from '@/utils/user/iaaa'
import { useLogin } from '@/stores/app'
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const { postLogin } = useLogin()
const task = useAsyncTask(async () => {
try {
Expand All @@ -27,10 +30,9 @@ const task = useAsyncTask(async () => {
}
})
const { token } = await resp.json<{ token: string }>()
login(token)
router.replace('/')
postLogin(token)
} catch (err) {
router.replace('/login')
router.replace({ path: '/auth/login', query: route.query })
throw new Error(await prettyHTTPError(err))
}
})
Expand Down
9 changes: 4 additions & 5 deletions apps/frontend/src/pages/auth/login/mail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
</template>

<script setup lang="ts">
import { http, login, prettyHTTPError } from '@/utils/http'
import { useLogin } from '@/stores/app'
import { http, prettyHTTPError } from '@/utils/http'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import type { SubmitEventPromise } from 'vuetify'
const { t } = useI18n()
const router = useRouter()
const toast = useToast()
const { postLogin } = useLogin()
const email = ref('')
const emailIcon = ref('mdi-send')
Expand Down Expand Up @@ -97,8 +97,7 @@ async function signin(ev: SubmitEventPromise) {
})
const { token } = await resp.json<{ token: string }>()
toast.success(t('hint.signin-success'))
login(token)
router.replace('/')
postLogin(token)
} catch (err) {
toast.error(t('hint.signin-wrong-credentials'))
}
Expand Down
15 changes: 5 additions & 10 deletions apps/frontend/src/pages/auth/login/password.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
</template>

<script setup lang="ts">
import { http, login } from '@/utils/http'
import { useLogin } from '@/stores/app'
import { http } from '@/utils/http'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import type { SubmitEventPromise } from 'vuetify'
const { t } = useI18n()
const router = useRouter()
const toast = useToast()
const { postLogin } = useLogin()
const username = ref('')
const password = ref('')
Expand Down Expand Up @@ -76,14 +76,9 @@ async function signin(ev: SubmitEventPromise) {
}
}
})
const { token, userId } = await resp.json<{ token?: string; userId?: string }>()
const { token } = await resp.json<{ token: string }>()
toast.success(t('hint.signin-success'))
if (token) {
login(token)
router.replace('/')
} else {
router.replace(`/initial?uid=${userId}`)
}
postLogin(token)
} catch (err) {
toast.error(t('hint.signin-wrong-credentials'))
}
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/pages/auth/verify.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const appState = useAppState()
const { hasMfaToken } = useMfa()
withI18nTitle('pages.verify')
if (!appState.loggedIn) router.replace('/login')
if (!appState.loggedIn) router.replace('/auth/login')
if (hasMfaToken.value) router.replace('/')
const hint = import.meta.env.VITE_VERIFY_HINT
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/pages/signup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ async function signup() {
const { token } = await resp.json<{ token: string }>()
login(token)
toast.success(t('hint.signup-success'))
router.push('/login')
router.push('auth/login')
} catch (error) {
toast.error(t('hint.signup-username-exists'))
return
Expand Down
3 changes: 2 additions & 1 deletion apps/frontend/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const router = createRouter({

router.beforeEach((to, from, next) => {
const appState = useAppState()
if (to.path.startsWith('/org') && !appState.loggedIn) return next('/login')
if (to.path.startsWith('/org') && !appState.loggedIn)
return next({ path: '/auth/login', query: { redirect: to.fullPath } })
return next()
})

Expand Down
24 changes: 23 additions & 1 deletion apps/frontend/src/stores/app.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineStore } from 'pinia'
import { computed, ref, watch } from 'vue'
import { useAsyncState, useLocalStorage, useTitle, watchDebounced } from '@vueuse/core'
import { http, isLoggedIn, userId } from '@/utils/http'
import { http, isLoggedIn, login, userId } from '@/utils/http'
import { useRoute, useRouter } from 'vue-router'
import type { IOrgProfile, IUserProfile } from '@/types'

Expand Down Expand Up @@ -106,3 +106,25 @@ export function useMfa() {
}
}
}

export function useLogin() {
const router = useRouter()
const route = useRoute()
return {
isLoggedIn,
postLogin: (token: string) => {
login(token)
if (route.query.redirect) {
router.replace(`${route.query.redirect}`)
} else {
router.replace('/')
}
},
doLogin: () => {
router.push({
path: '/auth/login',
query: { redirect: route.fullPath }
})
}
}
}
4 changes: 4 additions & 0 deletions apps/server/src/routes/problem/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const solutionScopedRoutes = defineRoutes(async (s) => {
200: Type.Object({
_id: Type.UUID(),
label: Type.String(),
problemId: Type.UUID(),
userId: Type.UUID(),
problemDataHash: Type.String(),
state: Type.Integer(),
score: Type.Number(),
Expand All @@ -81,6 +83,8 @@ const solutionScopedRoutes = defineRoutes(async (s) => {
{
projection: {
label: 1,
problemId: 1,
userId: 1,
problemDataHash: 1,
state: 1,
score: 1,
Expand Down

0 comments on commit 2371928

Please sign in to comment.