@xcpcio/board-app 0.6.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.eslintrc.json +6 -0
  2. package/LICENSE +1 -1
  3. package/README.md +13 -30
  4. package/cypress.config.ts +14 -0
  5. package/dist/_headers +3 -0
  6. package/dist/about.html +11 -0
  7. package/dist/assets/_...all_-27c7ae93.css +1 -0
  8. package/dist/assets/_...all_-d56798b5.js +3 -0
  9. package/dist/assets/_name_-8eab6137.js +1 -0
  10. package/dist/assets/about-a8cb8700.js +11 -0
  11. package/dist/assets/app-37f77a84.js +65 -0
  12. package/dist/assets/board-layout-deaedfc1.js +1 -0
  13. package/dist/assets/en-caedd340.js +1 -0
  14. package/dist/assets/home-49c336e5.js +1 -0
  15. package/dist/assets/index-a270cacd.css +5 -0
  16. package/dist/assets/index-layout-d65c80ea.js +1 -0
  17. package/dist/assets/test-0a3d6f7a.js +1 -0
  18. package/dist/assets/user-108782a1.js +1 -0
  19. package/dist/assets/virtual_pwa-register-1c1b9161.js +1 -0
  20. package/dist/assets/workbox-window.prod.es5-a7b12eab.js +2 -0
  21. package/dist/assets/zh-CN-86269804.js +1 -0
  22. package/dist/favicon-dark.svg +1 -0
  23. package/dist/favicon.svg +1 -0
  24. package/dist/index.html +1 -171
  25. package/dist/manifest.webmanifest +1 -0
  26. package/dist/pwa-192x192.png +0 -0
  27. package/dist/pwa-512x512.png +0 -0
  28. package/dist/robots.txt +4 -0
  29. package/dist/safari-pinned-tab.svg +41 -0
  30. package/dist/sitemap.xml +1 -0
  31. package/dist/ssr-manifest.json +486 -0
  32. package/dist/sw.js +1 -0
  33. package/dist/test.html +1 -0
  34. package/dist/workbox-b8d87ee1.js +1 -0
  35. package/package.json +94 -50
  36. package/public/_headers +3 -0
  37. package/public/favicon-dark.svg +1 -0
  38. package/public/favicon.svg +1 -0
  39. package/public/pwa-192x192.png +0 -0
  40. package/public/pwa-512x512.png +0 -0
  41. package/public/safari-pinned-tab.svg +41 -0
  42. package/src/App.vue +33 -0
  43. package/src/auto-imports.d.ts +909 -0
  44. package/src/components/ContestIndex.vue +227 -0
  45. package/src/components/Footer.vue +94 -0
  46. package/src/components/GoBack.vue +22 -0
  47. package/src/components/NavBar.vue +152 -0
  48. package/src/components/SearchInput.vue +50 -0
  49. package/src/components/TheCounter.vue +19 -0
  50. package/src/components/TheInput.vue +20 -0
  51. package/src/components/board/Balloon.vue +5 -0
  52. package/src/components/board/Board.vue +396 -0
  53. package/src/components/board/BottomStatistics.vue +159 -0
  54. package/src/components/board/ContestStateBadge.vue +41 -0
  55. package/src/components/board/Export.vue +75 -0
  56. package/src/components/board/Modal.vue +107 -0
  57. package/src/components/board/ModalMenu.vue +64 -0
  58. package/src/components/board/OptionsModal.vue +179 -0
  59. package/src/components/board/Progress.less +442 -0
  60. package/src/components/board/Progress.vue +229 -0
  61. package/src/components/board/SecondLevelMenu.vue +190 -0
  62. package/src/components/board/Standings.less +1162 -0
  63. package/src/components/board/Standings.vue +154 -0
  64. package/src/components/board/StandingsAnnotate.vue +38 -0
  65. package/src/components/board/Statistics.vue +77 -0
  66. package/src/components/board/SubmissionsTable.vue +312 -0
  67. package/src/components/board/SubmissionsTableModal.vue +52 -0
  68. package/src/components/board/TeamAwards.vue +93 -0
  69. package/src/components/board/TeamInfoModal.vue +128 -0
  70. package/src/components/board/TeamProblemBlock.vue +100 -0
  71. package/src/components/board/TeamUI.vue +161 -0
  72. package/src/components/board/Utility.vue +28 -0
  73. package/src/components/icon/GirlIcon.vue +80 -0
  74. package/src/components/icon/RightArrowIcon.vue +26 -0
  75. package/src/components/icon/StarIcon.vue +19 -0
  76. package/src/components/table/TablePagination.vue +108 -0
  77. package/src/components.d.ts +44 -0
  78. package/src/composables/dark.ts +4 -0
  79. package/src/composables/pagination.ts +81 -0
  80. package/src/composables/statistics.ts +280 -0
  81. package/src/composables/useLocalStorage.ts +29 -0
  82. package/src/composables/useQueryBoardData.ts +43 -0
  83. package/src/composables/utils.ts +11 -0
  84. package/src/layouts/board-layout.vue +14 -0
  85. package/src/layouts/default.vue +10 -0
  86. package/src/layouts/home.vue +12 -0
  87. package/src/layouts/index-layout.vue +15 -0
  88. package/src/main.ts +36 -0
  89. package/src/modules/README.md +11 -0
  90. package/src/modules/i18n.ts +52 -0
  91. package/src/modules/nprogress.ts +15 -0
  92. package/src/modules/pinia.ts +18 -0
  93. package/src/modules/pwa.ts +15 -0
  94. package/src/modules/toast.ts +10 -0
  95. package/src/pages/[...all].vue +34 -0
  96. package/src/pages/about.md +21 -0
  97. package/src/pages/hi/[name].vue +50 -0
  98. package/src/pages/index.vue +129 -0
  99. package/src/pages/test.vue +57 -0
  100. package/src/shims.d.ts +16 -0
  101. package/src/stores/user.ts +36 -0
  102. package/src/styles/color.css +51 -0
  103. package/src/styles/main.css +30 -0
  104. package/src/styles/markdown.css +28 -0
  105. package/src/styles/submission-status.css +123 -0
  106. package/src/types.ts +3 -0
  107. package/tsconfig.json +39 -0
  108. package/uno.config.ts +65 -0
  109. package/vite.config.ts +176 -0
  110. package/dist/favicon.ico +0 -0
  111. package/dist/umi.00ae29f6.js +0 -1
  112. package/dist/umi.bd64c248.css +0 -1
@@ -0,0 +1,190 @@
1
+ <script setup lang="ts">
2
+ import { useRouteQuery } from "@vueuse/router";
3
+ import type { Lang } from "@xcpcio/types";
4
+
5
+ export interface Item {
6
+ title?: string;
7
+
8
+ titles?: Map<Lang, string>;
9
+ defaultLang?: Lang;
10
+
11
+ keyword: string;
12
+ isDefault?: boolean;
13
+
14
+ link?: string;
15
+
16
+ isModal?: boolean;
17
+ }
18
+
19
+ const props = defineProps<{
20
+ items: Array<Item>;
21
+ currentItem: string;
22
+ queryParamName: string;
23
+ reverseOrder?: boolean;
24
+ // eslint-disable-next-line unused-imports/no-unused-vars
25
+ onChange?: (current: string) => void;
26
+ }>();
27
+
28
+ const emit = defineEmits(["update:currentItem"]);
29
+
30
+ const defaultType = computed(() => {
31
+ for (const item of props.items) {
32
+ if (item.isDefault) {
33
+ return item.keyword;
34
+ }
35
+ }
36
+
37
+ return props.items?.[0].keyword;
38
+ });
39
+
40
+ const currentItemFromRouteQuery = useRouteQuery(
41
+ props.queryParamName,
42
+ defaultType.value,
43
+ { transform: String },
44
+ );
45
+
46
+ const currentItem = computed({
47
+ get() {
48
+ return props.currentItem;
49
+ },
50
+ set(value) {
51
+ emit("update:currentItem", value);
52
+ },
53
+ });
54
+
55
+ const { t, locale } = useI18n();
56
+
57
+ function getTitle(item: Item) {
58
+ if (item.title) {
59
+ return t(item.title);
60
+ }
61
+
62
+ if (item.titles) {
63
+ return item.titles.get(locale.value as unknown as Lang) ?? item.titles.get(item.defaultLang!);
64
+ }
65
+
66
+ return "";
67
+ }
68
+
69
+ function isCurrent(item: Item): boolean {
70
+ if (currentItem.value === item.keyword) {
71
+ return true;
72
+ }
73
+
74
+ return false;
75
+ }
76
+
77
+ function onClick(item: Item) {
78
+ if (props.onChange) {
79
+ props.onChange(item.keyword);
80
+ }
81
+
82
+ if (item.link || item.isModal) {
83
+ return;
84
+ }
85
+
86
+ currentItem.value = item.keyword;
87
+ currentItemFromRouteQuery.value = item.keyword;
88
+ }
89
+
90
+ onMounted(() => {
91
+ (() => {
92
+ if (!(currentItemFromRouteQuery.value?.length > 0)) {
93
+ return;
94
+ }
95
+
96
+ (() => {
97
+ // Adapt the previous group query param
98
+ for (const item of props.items) {
99
+ if (!item.titles) {
100
+ continue;
101
+ }
102
+
103
+ for (const [_k, v] of item.titles) {
104
+ if (currentItemFromRouteQuery.value === v) {
105
+ currentItemFromRouteQuery.value = item.keyword;
106
+ return;
107
+ }
108
+ }
109
+ }
110
+ })();
111
+
112
+ currentItem.value = currentItemFromRouteQuery.value;
113
+ if (props.onChange) {
114
+ props.onChange(currentItemFromRouteQuery.value);
115
+ }
116
+ })();
117
+ });
118
+ </script>
119
+
120
+ <template>
121
+ <div
122
+ font-mono
123
+ flex
124
+ >
125
+ <div
126
+ class="mr-[-4px]"
127
+ flex
128
+ :class="{
129
+ 'flex-row-reverse': props.reverseOrder,
130
+ }"
131
+ >
132
+ <template
133
+ v-for="item in props.items"
134
+ :key="item.keyword"
135
+ >
136
+ <div
137
+ class="second-level-menu-item"
138
+ :class="[isCurrent(item) ? 'second-level-menu-item-current' : '']"
139
+ @click="onClick(item)"
140
+ >
141
+ <div>
142
+ <a
143
+ v-if="item.link"
144
+ :href="item.link"
145
+ target="_blank"
146
+ title="Resolver"
147
+ >
148
+ {{ getTitle(item) }}
149
+ </a>
150
+
151
+ <div
152
+ v-if="!item.link"
153
+ >
154
+ {{ getTitle(item) }}
155
+ </div>
156
+ </div>
157
+ </div>
158
+ </template>
159
+ </div>
160
+ </div>
161
+ </template>
162
+
163
+ <style scoped>
164
+ .second-level-menu-item {
165
+ height: 18px;
166
+ background: #333;
167
+ position: relative;
168
+ display: flex;
169
+ justify-content: center;
170
+ align-items: center;
171
+ color: #fff;
172
+ font-size: 14px;
173
+ font-weight: 700;
174
+ -webkit-transition: 0.7s;
175
+ transition: 0.7s;
176
+ cursor: pointer;
177
+ margin: 2px 4px !important;
178
+ padding: 4px !important;
179
+ box-sizing: content-box !important;
180
+ border-radius: 3px;
181
+ }
182
+
183
+ .second-level-menu-item:hover {
184
+ background: #f30;
185
+ }
186
+
187
+ .second-level-menu-item-current {
188
+ background: #f30;
189
+ }
190
+ </style>