chore(frontend): migrate Tailwind to Vite plugin
This commit is contained in:
6407
frontend/package-lock.json
generated
6407
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,44 +12,43 @@
|
||||
"api:update": "npm run api:schema && npm run api:types"
|
||||
},
|
||||
"dependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^6.0.5",
|
||||
"@intlify/unplugin-vue-i18n": "^11.1.2",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@stripe/stripe-js": "^3.0.10",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"@vueuse/head": "^2.0.0",
|
||||
"@stripe/stripe-js": "^9.4.0",
|
||||
"@vueuse/core": "^14.3.0",
|
||||
"@vueuse/head": "^0.9.8",
|
||||
"@xtiannyeto/vue-auth-social": "^0.1.9",
|
||||
"axios": "^1.6.7",
|
||||
"axios": "^1.16.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"i18n": "^0.15.1",
|
||||
"i18n": "^0.15.3",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"uuid": "^10.0.0",
|
||||
"vue": "^3.4.15",
|
||||
"pinia": "^3.0.4",
|
||||
"qrcode.vue": "^3.9.0",
|
||||
"typescript": "^6.0.3",
|
||||
"uuid": "^14.0.0",
|
||||
"vue": "^3.5.34",
|
||||
"vue-advanced-cropper": "^2.8.9",
|
||||
"vue-i18n": "^10.0.7",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-i18n": "^11.4.2",
|
||||
"vue-router": "^5.0.6",
|
||||
"vue-toastification": "^2.0.0-rc.5",
|
||||
"vue3-google-login": "^2.0.26",
|
||||
"vue3-google-login": "^2.1.3",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vuetify": "^3.5.6"
|
||||
"vuetify": "^4.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/webpack-env": "^1.18.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
||||
"@typescript-eslint/parser": "^8.34.0",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@tailwindcss/vite": "^4.2.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.59.2",
|
||||
"@typescript-eslint/parser": "^8.59.2",
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"openapi-typescript": "7.13.0",
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-visualizer": "^6.0.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^6.3.1",
|
||||
"vue-eslint-parser": "^10.1.3"
|
||||
"eslint": "^10.3.0",
|
||||
"eslint-plugin-tailwindcss": "^3.18.3",
|
||||
"eslint-plugin-vue": "^10.9.1",
|
||||
"prettier": "^3.8.3",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"tailwindcss": "^4.2.4",
|
||||
"vite": "^8.0.11",
|
||||
"vue-eslint-parser": "^10.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -62,6 +62,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.shell-container {
|
||||
@apply min-h-screen flex flex-row;
|
||||
@apply w-full font-sans;
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "tailwindcss";
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-hBackground: var(--h-background);
|
||||
--color-hOnBackground: var(--h-on-background);
|
||||
--color-hSurface: var(--h-surface);
|
||||
--color-hOnSurface: var(--h-on-surface);
|
||||
--color-hPrimary: var(--h-primary);
|
||||
--color-hOnPrimary: var(--h-on-primary);
|
||||
--color-hSecondary: var(--h-secondary);
|
||||
--color-hOnSecondary: var(--h-on-secondary);
|
||||
--color-hTertiary: var(--h-tertiary);
|
||||
--color-hOnTertiary: var(--h-on-tertiary);
|
||||
--color-hError: var(--h-error);
|
||||
--color-hOnError: var(--h-on-error);
|
||||
}
|
||||
|
||||
:root {
|
||||
--socialize-primary: #172033;
|
||||
@@ -129,13 +143,25 @@ div.card {
|
||||
}
|
||||
|
||||
button.primary {
|
||||
@apply btn;
|
||||
@apply min-w-24 w-full;
|
||||
@apply p-4;
|
||||
@apply flex flex-nowrap gap-4 items-center justify-center;
|
||||
@apply rounded-lg;
|
||||
@apply capitalize text-base font-sans font-medium;
|
||||
@apply px-10;
|
||||
@apply cursor-pointer;
|
||||
@apply bg-hPrimary text-hOnPrimary;
|
||||
@apply hover:brightness-125;
|
||||
}
|
||||
|
||||
button.secondary {
|
||||
@apply btn;
|
||||
@apply min-w-24 w-full;
|
||||
@apply p-4;
|
||||
@apply flex flex-nowrap gap-4 items-center justify-center;
|
||||
@apply rounded-lg;
|
||||
@apply capitalize text-base font-sans font-medium;
|
||||
@apply px-10;
|
||||
@apply cursor-pointer;
|
||||
@apply bg-hSecondary text-hOnSecondary;
|
||||
@apply hover:brightness-125;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.avatar {
|
||||
@apply inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full font-black uppercase;
|
||||
background: linear-gradient(135deg, rgba(15, 118, 110, 0.16) 0%, rgba(255, 138, 61, 0.18) 100%);
|
||||
|
||||
@@ -278,6 +278,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.cropper-card {
|
||||
@apply flex flex-col gap-5 rounded-[1.75rem] border p-5;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.brand-logo-root {
|
||||
@apply inline-flex items-center;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.brand-mark-root {
|
||||
@apply inline-flex items-center justify-center overflow-hidden;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.card-content {
|
||||
@apply p-6;
|
||||
}
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.login-page {
|
||||
@apply flex min-h-screen w-full items-stretch justify-center sm:items-center sm:p-4;
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.visibility-toggle {
|
||||
@apply cursor-pointer;
|
||||
@apply transition-opacity duration-300;
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
form {
|
||||
@apply bg-hSurface rounded-xl p-4;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -255,6 +255,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -483,6 +483,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -219,6 +219,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -333,6 +333,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.approval-panel {
|
||||
@apply relative flex w-11 justify-center self-start;
|
||||
}
|
||||
|
||||
@@ -244,6 +244,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.comment-composer {
|
||||
@apply flex flex-col gap-3 rounded-[1.25rem] border p-4;
|
||||
background: #fffdf8;
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.timeline-list {
|
||||
@apply flex flex-col gap-4;
|
||||
}
|
||||
|
||||
@@ -1357,6 +1357,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.editor-shell {
|
||||
@apply mx-auto flex w-full max-w-[110rem] flex-col gap-5 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -1419,6 +1419,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply flex w-full flex-col gap-4 px-4 py-5 md:px-6;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.feedback-entry {
|
||||
@apply fixed bottom-5 right-5 z-50;
|
||||
}
|
||||
|
||||
@@ -620,6 +620,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.feedback-dialog {
|
||||
@apply overflow-hidden rounded-lg border;
|
||||
background: #fffaf2;
|
||||
|
||||
@@ -446,6 +446,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.feedback-detail-page {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-5 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -266,6 +266,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.feedback-review-page {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-5 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -246,6 +246,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.feedback-detail-page {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-5 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.my-feedback-page {
|
||||
@apply mx-auto flex w-full max-w-6xl flex-col gap-5 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -452,6 +452,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.organization-settings-shell {
|
||||
@apply mx-auto flex w-full max-w-6xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply flex flex-col gap-6;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.settings-shell {
|
||||
@apply mx-auto grid w-full max-w-7xl gap-4 px-5 py-8 md:px-8 xl:grid-cols-[16rem_minmax(0,1fr)];
|
||||
}
|
||||
|
||||
@@ -346,6 +346,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply flex flex-col gap-6;
|
||||
}
|
||||
|
||||
@@ -318,6 +318,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.approval-workflow-editor {
|
||||
@apply flex flex-col gap-3;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.time-zone-select {
|
||||
@apply rounded-[1rem] border px-4 py-3 text-sm;
|
||||
background: #fffdf8;
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.calendar-shell {
|
||||
@apply mx-auto w-full max-w-7xl px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -317,6 +317,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.page-shell {
|
||||
@apply mx-auto flex w-full max-w-6xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -829,6 +829,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.workspace-settings-shell {
|
||||
@apply mx-auto flex w-full max-w-6xl flex-col gap-6 px-5 py-8 md:px-8;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.side-container {
|
||||
@apply sticky top-0 z-20 flex flex-col gap-4 px-5 py-4 md:flex-row md:items-center md:justify-between;
|
||||
background: rgba(255, 250, 242, 0.82);
|
||||
|
||||
@@ -634,6 +634,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.app-sidebar {
|
||||
@apply flex h-full w-[19rem] flex-shrink-0 flex-col px-4 pt-4 transition-[width,padding] duration-200;
|
||||
border-right: 1px solid rgba(23, 32, 51, 0.08);
|
||||
|
||||
@@ -153,6 +153,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.sidebar-workspace {
|
||||
@apply relative flex flex-col gap-2;
|
||||
}
|
||||
|
||||
@@ -322,6 +322,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.label {
|
||||
@apply hidden text-nowrap md:inline;
|
||||
}
|
||||
|
||||
@@ -262,6 +262,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.site-menu {
|
||||
@apply sticky top-0 z-30 w-full;
|
||||
background: rgba(255, 250, 242, 0.9);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.public-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.public-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.landing-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.public-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.public-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/assets/main.css";
|
||||
.public-page {
|
||||
@apply min-h-screen w-full;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
hBackground: "var(--h-background)",
|
||||
hOnBackground: "var(--h-on-background)",
|
||||
hSurface: "var(--h-surface)",
|
||||
hOnSurface: "var(--h-on-surface)",
|
||||
hPrimary: "var(--h-primary)",
|
||||
hOnPrimary: "var(--h-on-primary)",
|
||||
hSecondary: "var(--h-secondary)",
|
||||
hOnSecondary: "var(--h-on-secondary)",
|
||||
hTertiary: "var(--h-tertiary)",
|
||||
hOnTertiary: "var(--h-on-tertiary)",
|
||||
hError: "var(--h-error)",
|
||||
hOnError: "var(--h-on-error)",
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vite'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||
import { resolve } from 'path'
|
||||
@@ -8,6 +9,7 @@ import { visualizer } from 'rollup-plugin-visualizer'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ isSsrBuild }) => ({
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
visualizer({
|
||||
filename: './dist/stats.html',
|
||||
open: true, // Automatically opens in browser
|
||||
@@ -38,11 +40,22 @@ export default defineConfig(({ isSsrBuild }) => ({
|
||||
sourcemap: true, // Enable source maps for debugging
|
||||
rollupOptions: {
|
||||
output: isSsrBuild ? undefined : {
|
||||
manualChunks: {
|
||||
vue: ['vue'],
|
||||
vuetify: ['vuetify'],
|
||||
vendor: ['lodash', 'axios'], // adjust based on your deps
|
||||
vuedraggable: ['vuedraggable']
|
||||
manualChunks(id) {
|
||||
if (id.includes('/node_modules/vue/')) {
|
||||
return 'vue'
|
||||
}
|
||||
|
||||
if (id.includes('/node_modules/vuetify/')) {
|
||||
return 'vuetify'
|
||||
}
|
||||
|
||||
if (id.includes('/node_modules/vuedraggable/')) {
|
||||
return 'vuedraggable'
|
||||
}
|
||||
|
||||
if (id.includes('/node_modules/lodash/') || id.includes('/node_modules/axios/')) {
|
||||
return 'vendor'
|
||||
}
|
||||
},
|
||||
format: 'es',
|
||||
entryFileNames: '[name].[hash].js',
|
||||
|
||||
Reference in New Issue
Block a user