chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports) - Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier - Add root scripts: format, format:check, lint, lint:fix - Reformat 257 files across admin-web, ops-web, desktop-client, packages - Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters - Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex - Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,86 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import { DeleteOutlined, PictureOutlined } from "@ant-design/icons-vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { CreateKolPackageRequest } from "@geo/shared-types";
|
||||
import { DeleteOutlined, PictureOutlined } from '@ant-design/icons-vue'
|
||||
import type { CreateKolPackageRequest } from '@geo/shared-types'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import CoverPickerModal from "@/components/CoverPickerModal.vue";
|
||||
import { imagesApi, resolveApiURL } from "@/lib/api";
|
||||
import { deriveCoverFileName } from "@/lib/cover-requirements";
|
||||
import CoverPickerModal from '@/components/CoverPickerModal.vue'
|
||||
import { imagesApi, resolveApiURL } from '@/lib/api'
|
||||
import { deriveCoverFileName } from '@/lib/cover-requirements'
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean;
|
||||
initialValue?: Partial<CreateKolPackageRequest>;
|
||||
}>();
|
||||
open: boolean
|
||||
initialValue?: Partial<CreateKolPackageRequest>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:open", value: boolean): void;
|
||||
(e: "submit", value: CreateKolPackageRequest): void;
|
||||
}>();
|
||||
(e: 'update:open', value: boolean): void
|
||||
(e: 'submit', value: CreateKolPackageRequest): void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n();
|
||||
const coverPickerOpen = ref(false);
|
||||
const { t } = useI18n()
|
||||
const coverPickerOpen = ref(false)
|
||||
|
||||
const formState = reactive<CreateKolPackageRequest>({
|
||||
name: "",
|
||||
description: "",
|
||||
industry: "",
|
||||
name: '',
|
||||
description: '',
|
||||
industry: '',
|
||||
tags: [],
|
||||
price_note: "",
|
||||
cover_url: "",
|
||||
});
|
||||
price_note: '',
|
||||
cover_url: '',
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.open,
|
||||
(isOpen) => {
|
||||
if (isOpen) {
|
||||
Object.assign(formState, {
|
||||
name: props.initialValue?.name || "",
|
||||
description: props.initialValue?.description || "",
|
||||
industry: props.initialValue?.industry || "",
|
||||
name: props.initialValue?.name || '',
|
||||
description: props.initialValue?.description || '',
|
||||
industry: props.initialValue?.industry || '',
|
||||
tags: [...(props.initialValue?.tags || [])],
|
||||
price_note: props.initialValue?.price_note || "",
|
||||
cover_url: props.initialValue?.cover_url || "",
|
||||
});
|
||||
return;
|
||||
price_note: props.initialValue?.price_note || '',
|
||||
cover_url: props.initialValue?.cover_url || '',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
coverPickerOpen.value = false;
|
||||
coverPickerOpen.value = false
|
||||
},
|
||||
);
|
||||
)
|
||||
|
||||
const coverPreviewUrl = computed(() => resolveApiURL(formState.cover_url));
|
||||
const coverFileName = computed(() => deriveCoverFileName(formState.cover_url));
|
||||
const coverPreviewUrl = computed(() => resolveApiURL(formState.cover_url))
|
||||
const coverFileName = computed(() => deriveCoverFileName(formState.cover_url))
|
||||
|
||||
function handleOk() {
|
||||
if (!formState.name.trim()) {
|
||||
message.warning(t("kol.manage.packageForm.nameRequired"));
|
||||
return;
|
||||
message.warning(t('kol.manage.packageForm.nameRequired'))
|
||||
return
|
||||
}
|
||||
emit("submit", { ...formState, tags: [...formState.tags] });
|
||||
emit("update:open", false);
|
||||
emit('submit', { ...formState, tags: [...formState.tags] })
|
||||
emit('update:open', false)
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
emit("update:open", false);
|
||||
emit('update:open', false)
|
||||
}
|
||||
|
||||
function handleRemoveCover() {
|
||||
formState.cover_url = "";
|
||||
formState.cover_url = ''
|
||||
}
|
||||
|
||||
function handleCoverConfirmed(payload: { url: string }) {
|
||||
formState.cover_url = resolveApiURL(payload.url);
|
||||
formState.cover_url = resolveApiURL(payload.url)
|
||||
}
|
||||
|
||||
async function uploadCover(file: File) {
|
||||
const uploaded = await imagesApi.upload(file);
|
||||
const uploaded = await imagesApi.upload(file)
|
||||
return {
|
||||
url: uploaded.url,
|
||||
fileName: uploaded.name,
|
||||
assetId: uploaded.id,
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -97,7 +97,7 @@ async function uploadCover(file: File) {
|
||||
<a-form-item :label="t('common.title')" required>
|
||||
<a-input v-model:value="formState.name" :placeholder="t('common.inputPlease')" />
|
||||
</a-form-item>
|
||||
|
||||
|
||||
<a-form-item :label="t('common.description')">
|
||||
<a-textarea v-model:value="formState.description" :rows="3" />
|
||||
</a-form-item>
|
||||
@@ -124,30 +124,34 @@ async function uploadCover(file: File) {
|
||||
|
||||
<a-form-item :label="t('kol.manage.packageForm.cover')">
|
||||
<div class="package-cover-field">
|
||||
<button
|
||||
type="button"
|
||||
class="package-cover-picker"
|
||||
@click="coverPickerOpen = true"
|
||||
>
|
||||
<button type="button" class="package-cover-picker" @click="coverPickerOpen = true">
|
||||
<template v-if="coverPreviewUrl">
|
||||
<img :src="coverPreviewUrl" :alt="t('kol.manage.packageForm.cover')" class="package-cover-picker__image" />
|
||||
<img
|
||||
:src="coverPreviewUrl"
|
||||
:alt="t('kol.manage.packageForm.cover')"
|
||||
class="package-cover-picker__image"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="package-cover-picker__empty">
|
||||
<PictureOutlined class="package-cover-picker__icon" />
|
||||
<strong>{{ t("kol.manage.packageForm.selectCover") }}</strong>
|
||||
<span>{{ t("kol.manage.packageForm.coverHint") }}</span>
|
||||
<strong>{{ t('kol.manage.packageForm.selectCover') }}</strong>
|
||||
<span>{{ t('kol.manage.packageForm.coverHint') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</button>
|
||||
|
||||
<div class="package-cover-actions">
|
||||
<a-button @click="coverPickerOpen = true">
|
||||
{{ coverPreviewUrl ? t("kol.manage.packageForm.changeCover") : t("kol.manage.packageForm.selectCover") }}
|
||||
{{
|
||||
coverPreviewUrl
|
||||
? t('kol.manage.packageForm.changeCover')
|
||||
: t('kol.manage.packageForm.selectCover')
|
||||
}}
|
||||
</a-button>
|
||||
<a-button v-if="coverPreviewUrl" danger @click="handleRemoveCover">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
{{ t("kol.manage.packageForm.removeCover") }}
|
||||
{{ t('kol.manage.packageForm.removeCover') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,7 +190,9 @@ async function uploadCover(file: File) {
|
||||
overflow: hidden;
|
||||
background: #f8fafc;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.package-cover-picker:hover {
|
||||
|
||||
Reference in New Issue
Block a user