update style upload / connect api

This commit is contained in:
2024-04-22 00:23:39 +07:00
parent dfc314e16e
commit a871a8e178
8 changed files with 819 additions and 292 deletions

22
package-lock.json generated
View File

@@ -10,7 +10,9 @@
"dependencies": {
"@mdi/font": "5.9.55",
"@trpc/client": "^10.45.2",
"filereader": "^0.10.3",
"roboto-fontface": "*",
"thai-id-validator": "^1.1.3",
"vue": "^3.2.13",
"vue-router": "^4.3.0",
"vuetify": "^3.0.0-beta.0",
@@ -5978,6 +5980,11 @@
"node": ">=8.9.0"
}
},
"node_modules/filereader": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz",
"integrity": "sha512-7F8w6GSXuHLN80ukaVOcHgBaiTRHUZr8GeEhNdqfAECcnBoROg4i8hTl+KqtF4yUPffOJVHEFg4iDJb7xIYFng=="
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz",
@@ -13073,6 +13080,11 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/thai-id-validator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/thai-id-validator/-/thai-id-validator-1.1.3.tgz",
"integrity": "sha512-Cv7Nt4YbrqEwxfwhfW1Z+5nb0fSEC48FgKkeZLb5ebolHVbGTwofhaN+D7dFQvHX4sT/ea503edEFEs71lgf5A=="
},
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz",
@@ -19371,6 +19383,11 @@
}
}
},
"filereader": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz",
"integrity": "sha512-7F8w6GSXuHLN80ukaVOcHgBaiTRHUZr8GeEhNdqfAECcnBoROg4i8hTl+KqtF4yUPffOJVHEFg4iDJb7xIYFng=="
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz",
@@ -24913,6 +24930,11 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"thai-id-validator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/thai-id-validator/-/thai-id-validator-1.1.3.tgz",
"integrity": "sha512-Cv7Nt4YbrqEwxfwhfW1Z+5nb0fSEC48FgKkeZLb5ebolHVbGTwofhaN+D7dFQvHX4sT/ea503edEFEs71lgf5A=="
},
"thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz",

View File

@@ -11,7 +11,9 @@
"dependencies": {
"@mdi/font": "5.9.55",
"@trpc/client": "^10.45.2",
"filereader": "^0.10.3",
"roboto-fontface": "*",
"thai-id-validator": "^1.1.3",
"vue": "^3.2.13",
"vue-router": "^4.3.0",
"vuetify": "^3.0.0-beta.0",

View File

@@ -11,6 +11,7 @@
</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Thai:wght@100;200;300;400;500;600;700&display=swap"
rel="stylesheet">

View File

@@ -20,67 +20,96 @@
<v-stepper-window>
<!-- -------------------------------------------step1----------------------------------------------- -->
<v-stepper-window-item :key="`${1}-content`" :value="1">
<v-card color="" class="text-sub2">
<v-stepper-window-item
:key="`${1}-content`"
:value="1"
class="text-sub2"
>
<!-- <v-card color="" class="text-sub2"> -->
<div>วงท 1</div>
<div class="text-subtitle">
อมลสวนต
<hr class="my-3" />
</div>
<v-row class="text-center">
<v-col class="py-3" cols="12" md="6">
<!-- {{ form1 }} -->
<v-form fast-fail @submit.prevent v-model="form1">
<v-row class="px-2">
<v-col class="py-3" cols="12" md="12">
<v-text-field
label="ชื่อ / Name"
variant="solo"
:rules="rules.required"
v-model="payload.firstName"
></v-text-field>
<v-text-field
label="นามสกุล / LastName"
variant="solo"
:rules="rules.required"
v-model="payload.lastName"
></v-text-field>
<v-text-field
label="เลขบัตรประชาชน / ID card number"
variant="solo"
:rules="rules.id"
v-model="payload.cid"
counter
></v-text-field>
<v-row>
<v-col class="py-3" cols="12" md="6">
<!-- <v-text-field
label="อายุ / Age"
variant="solo"
:rules="rules.required"
counter-value="true"
></v-text-field> -->
<v-text-field
label="อายุ / Age"
variant="solo"
type="number"
min="40"
v-model.number="payload.age"
></v-text-field>
</v-col>
<v-col class="py-3" cols="12" md="6">
<v-text-field
label="อาชีพ / Occupation"
variant="solo"
:rules="rules.required"
v-model="payload.job"
></v-text-field>
<!-- <v-select
label="อาชีพ / Occupation"
:items="items"
variant="solo"
item-title="text"
return-object
></v-select> -->
</v-col>
</v-row>
<v-text-field
label="ประวัติการศึกษา / Education"
variant="solo"
:rules="rules.required"
v-model="payload.education"
></v-text-field>
<v-text-field
label="เบอร์โทรศัพท์"
variant="solo"
:rules="rules.tel"
v-model="payload.phone"
></v-text-field>
<div class="text-small text-left font-weight-medium">
งผาน OTP
</div>
</v-col>
<v-col>
<v-card color="#4C884C" class="pa-5" elevated>
<v-col class="d-none">
<v-card
color="#4C884C"
class="pa-5 text-center h-100"
elevated
>
<div class="text-sub text-left">
<v-icon icon="mdi-plus-box-multiple"></v-icon>
เพมรปภาพ
</div>
<!-- {{url}} -->
<v-avatar size="200" color="grey" class="elevation-3">
<v-img :src="url" v-if="url"></v-img>
<v-icon dark v-else size="80"> mdi-account </v-icon>
@@ -100,11 +129,25 @@
</v-card>
</v-col>
</v-row>
</v-card>
<!-- <v-btn @click.prevent="e1++" :disabled="!form1">next</v-btn> -->
<v-stepper-actions
type="submit"
:disabled="disabled && !form1"
@click:next="next"
@click:prev="prev"
></v-stepper-actions>
</v-form>
<!-- </v-card> -->
</v-stepper-window-item>
<!-- -------------------------------------------step2----------------------------------------------- -->
<v-stepper-window-item :key="`${2}-content`" :value="2">
<v-card color="" class="text-sub2">
<v-form
fast-fail
@submit.prevent
v-model="form2"
class="text-sub2"
>
<div>วงท 2</div>
<div class="text-subtitle">
อมลการสมครสว.
@@ -115,11 +158,12 @@
ประสงคจะสมครในกล*
</v-col>
<v-col class="py-3 col2" cols="12" md="12">
<v-radio-group v-model="radio">
<!-- {{payload.group}} -->
<v-radio-group v-model.number="payload.group">
<v-radio
class="text-sub2"
:label="item.text"
:value="item.text"
:label="item.name"
:value="item.id"
v-for="(item, i) in items"
:key="i"
></v-radio>
@@ -148,9 +192,9 @@
label="จังหวัด"
:items="provinceItems"
variant="solo"
item-title="provinceNameTh"
return-object
v-model="province"
item-title="name"
item-value="id"
v-model.number="payload.province"
placeholder="จังหวัด"
@update:modelValue="filterData"
></v-autocomplete>
@@ -173,26 +217,54 @@
เปนทงของสถานศกษาทเคยศกษา
ดตอกนไมอยกว 2 การศกษา
</div>
<!-- {{ district }} -->
<!-- {{ payload.zone }} -->
<v-autocomplete
label="อำเภอ / เขต"
:items="districtItems"
variant="solo"
item-title="districtNameTh"
return-object
v-model="district"
item-title="name"
item-value="id"
v-model.number="payload.zone"
placeholder="อำเภอ / เขต"
:disabled="payload.province == null"
></v-autocomplete>
</div>
</v-card>
</v-col>
</v-row>
</v-card>
<div class="btn-next">
<v-btn @click="e1--" variant="text" class="float-left"
>Previous</v-btn
>
<!-- <v-spacer></v-spacer> -->
<v-btn
@click="e1++"
:disabled="
payload.zone == null ||
payload.province == null ||
payload.group == null
"
variant="tonal"
class="float-right"
>next</v-btn
>
</div>
<!-- <v-stepper-actions
type="submit"
:disabled="disabled"
@click:next="next"
@click:prev="prev"
></v-stepper-actions> -->
</v-form>
</v-stepper-window-item>
<!-- -------------------------------------------step3----------------------------------------------- -->
<v-stepper-window-item :key="`${3}-content`" :value="3">
<v-card color="" class="text-sub2">
<v-stepper-window-item
:key="`${3}-content`"
:value="3"
class="text-sub2"
>
<div>วงท 3</div>
<div class="text-subtitle">
ดยนในฐานะสมาชกรฐสภา (สว.)
@@ -214,32 +286,33 @@
</v-row>
</v-col></v-row
>
<!-- {{ option1 }} -->
<v-row
v-for="(item, i) in opnitem1"
v-for="(item, i) in option1"
:key="i"
align="center"
justify="center"
style="border-bottom: 1px solid #e4e4e4"
>
<v-col class="">
{{ item.text }}
{{ item.name }}
</v-col>
<v-col>
<v-radio-group inline hide>
<v-radio
class="text-sub2"
value="เห็นด้วย"
@click="item.check = 'เห็นด้วย'"
value="agree"
@click="item.choice = 'agree'"
></v-radio>
<v-radio
class="text-sub2"
value="ไม่เห็นด้วย"
@click="item.check = 'ไม่เห็นด้วย'"
value="disagree"
@click="item.choice = 'disagree'"
></v-radio>
<v-radio
class="text-sub2"
value="พิจารณา"
@click="item.check = 'พิจารณา'"
value="deciding"
@click="item.choice = 'deciding'"
></v-radio>
</v-radio-group>
</v-col>
@@ -261,40 +334,41 @@
</v-row> -->
</v-col></v-row
>
<!-- {{option2}} -->
<v-row
v-for="(item, i) in opnitem2"
v-for="(item, i) in option2"
:key="i"
align="center"
justify="center"
style="border-bottom: 1px solid #e4e4e4"
>
<v-col class="text-sub2 font-weight-medium" cols="12">
{{ item.text }}
{{ item.name }}
</v-col>
<v-col cols="12">
<v-radio-group inline class="col4">
<v-radio
class="text-sub2"
value="เห็นด้วย"
@click="item.check = 'เห็นด้วย'"
value="agree"
@click="item.choice = 'agree'"
label="เห็นด้วย"
></v-radio>
<v-radio
class="text-sub2"
value="ไม่เห็นด้วย"
@click="item.check = 'ไม่เห็นด้วย'"
value="disagree"
@click="item.choice = 'disagree'"
label="ไม่เห็นด้วย"
></v-radio>
<v-radio
class="text-sub2"
value="พิจารณา"
@click="item.check = 'พิจารณา'"
value="deciding"
@click="item.choice = 'deciding'"
label="พิจารณา"
></v-radio>
<v-radio
class="text-sub2"
value="ไม่แสดงความเห็น"
@click="item.check = 'ไม่แสดงความเห็น'"
value="ignore"
@click="item.choice = 'ignore'"
label="ไม่แสดงความเห็น"
></v-radio>
</v-radio-group>
@@ -311,16 +385,20 @@
label=""
variant="solo"
bg-color="#F2EBD1"
v-model="payload.vision"
></v-textarea>
</v-card>
</v-col>
</v-row>
</v-card>
</v-stepper-window-item>
<!-- -------------------------------------------step4----------------------------------------------- -->
<v-stepper-window-item :key="`${4}-content`" :value="4">
<v-card class="mt-8 text-sub">
<v-stepper-window-item
:key="`${4}-content`"
:value="4"
class="text-sub"
>
<div>
<div>วงท 4</div>
<div class="text-subtitle">
คำถามอนเกยวกบสว.
@@ -334,6 +412,7 @@
label="เหตุผลความตั้งใจในการลงสมัคร สว. ครั้งนี้"
variant="solo"
bg-color="#F2EBD1"
v-model="payload.reason"
></v-textarea>
</v-card>
<v-card class="mt-8 text-sub">
@@ -341,52 +420,73 @@
องทางการตดต (สำหรบเปดเผยตอสาธารณะ)
</div>
<v-row>
<v-col cols="12" md="4">
<v-col cols="12" md="12">
<v-text-field
variant="solo"
bg-color="#F2EBD1"
label="โทรศัพท์"
v-model="payload.public_phone"
:rules="rules.tel"
></v-text-field
></v-col>
</v-row>
<v-row>
<v-col
<v-col cols="12" md="4"
><v-text-field
variant="solo"
bg-color="#F2EBD1"
label="Facebook"
v-model="payload.facebook"
></v-text-field
></v-col>
<v-col
<v-col cols="12" md="4"
><v-text-field
variant="solo"
bg-color="#F2EBD1"
label="X"
v-model="payload.twitter"
></v-text-field
></v-col>
<v-col
<v-col cols="12" md="4"
><v-text-field
variant="solo"
bg-color="#F2EBD1"
label="TikTok"
v-model="payload.tiktok"
></v-text-field
></v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-text-field
variant="solo"
bg-color="#F2EBD1"
label="email"
v-model="payload.email"
></v-text-field
></v-col>
<v-col cols="12" md="6">
<v-text-field
variant="solo"
bg-color="#F2EBD1"
v-model="payload.otherSocial"
label="ช่องทางอื่นๆ"
></v-text-field>
<div class="text-sub">องทางการตดต (สำหรบทมงาน)*</div>
></v-text-field
></v-col>
</v-row>
<!-- <div class="text-sub">องทางการตดต (สำหรบทมงาน)*</div>
<v-row>
<v-col cols="12" md="4">
<v-text-field
variant="solo"
bg-color="#F2EBD1"
label="โทรศัพท์"
:rules="rules.tel"
v-model="payload.public_phone"
></v-text-field
></v-col>
</v-row>
</v-row> -->
</v-card>
<v-card class="mt-8 text-sub">
<div class="text-sub">กรณายนยนการสงคำตอบ</div>
@@ -394,6 +494,7 @@
color="success"
value="true"
style="font-size: 24px"
v-model="check"
></v-checkbox>
<div class="text-sub3">
าพเจาขอสาบานตนตอสงศกดทธงหลายทาพเจานบถ
@@ -406,17 +507,24 @@
ขอภยนตรายและความวงปวงจงบงเกดแกาพเจ โดยพล
*นยนการสงคำตอบ เพอประกาศตวเปนผสมครเป สว.67
</div>
<div class="text-right">
<v-btn color="#DD6C31" class="mt-4" height="40">
<div class="text-center mb-5">
<v-btn
color="#DD6C31"
class="mt-4"
height="40"
@click="submit"
:disabled="!check"
>
<span class="text-sub">นท</span>
</v-btn>
</div>
</v-card>
</v-card>
</div>
</v-stepper-window-item>
</v-stepper-window>
<v-stepper-actions
v-show="e1 == 3 || el == 4"
:disabled="disabled"
@click:next="next"
@click:prev="prev"
@@ -427,14 +535,23 @@
</v-container>
</template>
<script>
import Provinces from "./provinces.json";
import Districts from "./districts.json";
// import Provinces from "./provinces.json";
// import Districts from "./districts.json";
import { client } from "@/utils/trpc";
import validateThaiID from "thai-id-validator";
// client.info.getAllGroups.query({}).then(console.log);
export default {
watch: {
image(val) {
console.log(val);
if (val == undefined) {
this.url=null
this.url = null;
this.image = null;
}
},
url(val) {
if (val) {
this.payload.image = val;
}
},
},
@@ -446,18 +563,112 @@ export default {
? "next"
: undefined;
},
// isIdCardValid() {
// return this.$refs.form.validate();
// },
// // ถ้าเลขบัตรประชาชนไม่ถูกต้องให้ปุ่ม Next ถูก disable
// isNextDisabled() {
// return !this.isIdCardValid;
// }
},
data() {
return {
check: false,
form1: false,
form2: false,
form3: false,
form4: false,
rules: {
// ^[a-zA-Z0-9?><;,{}[\]\-_+=!@#$%\^&*|']*$
space: (v) => /^[^ ]+$/.test(v) || "must not contain spaces.",
username: (v) =>
/^[a-zA-Z0-9?><;.,{}[\]\-_+=!@#$%&*|']*$/.test(v) ||
"Username ไม่ถูกต้อง",
name_eng: (v) => {
if (v === null || v === undefined) {
return false;
}
const pattern = /^[A-Za-z]+$/;
return (
(pattern.test(v) && v.length >= 8) ||
"English name must contain only letters and be 8 characters or more"
);
},
name_thai: (v) => {
const pattern = /[\u0E00-\u0E7F']/;
return pattern.test(v) || "ใช้ภาษาไทยเท่านั้น";
},
required: [(value) => !!value || "Please fill out."],
password: (v) =>
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/.test(v) ||
// /^[a-zA-Z0-9?><;.,{}[\]\-_+=!@#$%\^&*|']*$/.test(v) ||
"The password must contain lowercase letters ( a - z ), uppercase letters ( A - Z ), and numbers ( 0 - 9 ), with a length of 8 or more.",
// 'รหัสผ่านจะต้องประกอบด้วยตัวพิมพ์เล็ก ( a - z ) ตัวอักษรพิมพ์ใหญ่ ( A - Z ) และตัวเลข ( 0 - 9 ) ความยาว 8 ขึ้นไป',
passwordsMatch: (v) => {
return v === this.FormRegister.password || "Passwords do not match";
},
min: (v) => v.length >= 6 || v.slice(0, 5),
tel: [
(v) =>
// (parseInt(v) == v && v.length == 10) || 'เบอร์โทรไม่ถูกต้อง',
/^([0-9]{10})$/.test(v) || "Invalid phone number",
],
id: [
(v) =>
(parseInt(v) == v && v.length == 13 && validateThaiID(v)) ||
"Invalid ID card number",
],
email: [
(value) => {
const pattern =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return pattern.test(value) || "invalid email";
},
],
},
payload: {
firstName: null,
lastName: null,
title: "",
cid: null,
age: null,
phone: null,
public_phone: null,
facebook: null,
twitter: null,
tiktok: null,
otherSocial: null,
image: null,
email: null,
job: null,
education: null,
vision: null,
reason: null,
group: null,
zone: null,
province: null,
// opinions: [
// {
// opinionId: "",
// choice: "",
// },
// ],
},
url: null,
image: null,
province: null,
district: null,
districtItems: [],
provinceItems: Provinces,
provinceItems: [],
radio: null,
e1: 1,
steps: 4,
option1: [],
option2: [],
opnitem2: [
{ text: "แก้ไข มาตรา 112", idx: 1, check: null },
{
@@ -515,62 +726,146 @@ export default {
idx: 14,
},
],
items: [
{ text: "กลุ่มบริหารราชการแผ่นดินและความมั่นคง", idx: 1 },
{ text: "กลุ่มกฎหมายกระบวนการยุติธรรม", idx: 2 },
{ text: "กลุ่มการศึกษา", idx: 3 },
{ text: "กลุ่มการสาธารณสุข", idx: 4 },
{ text: "กลุ่มอาชีพทำนา ปลูกพืชล้มลุก", idx: 5 },
{ text: "กลุ่มอาชีพทำสวน ป่าไม้ ปศุสัตว์ ประมง", idx: 6 },
{ text: "กลุ่มพนักงานหรือลูกจ้างของบุคคล(ไม่ใช่หน่วยงานรัฐ)", idx: 7 },
{
text: "กลุ่มผู้ประกอบอาชีพด้านสิ่งแวดล้อม ผังเมือง อสังหาริมทรัพย์และสาธารณูปโภค ทรัพยากรธรรมชาติ พลังงาน",
idx: 8,
},
{ text: "กลุ่มผู้ประกอบกิจการ หรือ SME", idx: 9 },
{ text: "กลุ่มผู้ประกอบกิจการอื่นนอกจากข้อ (9)", idx: 10 },
{ text: "กลุ่มผู้ประกอบธุรกิจหรืออาชีพด้านการท่องเที่ยว", idx: 11 },
{ text: "กลุ่มผู้ประกอบอุตสาหกรรม", idx: 12 },
{
text: "กลุ่มผู้ประกอบอาชีพด้านวิทยาศาสตร์ เทคโนโลยี การสื่อสาร การพัฒนานวัตรกรรม",
idx: 13,
},
{ text: "กลุ่มสตรี", idx: 14 },
{
text: "กลุ่มผู้สูงอายุ คนพิการหรือทุพพลภาพ กลุ่มชาติพันธุ์ กลุ่มอัตลักษณ์อื่น",
idx: 15,
},
{ text: "กลุ่มศิลปะ วัฒนธรรม ดนตรี การแสดงและบันเทิง", idx: 16 },
{ text: "กลุ่มประชาสังคม องค์กรสาธารณประโยชน์", idx: 17 },
{ text: "กลุ่มนักกีฬา สื่อสารมวลชน ผู้สร้างสรรค์วรรณกรรม", idx: 18 },
{ text: "กลุ่มผู้ประกอบวิชาชีพ ผู้ประกอบอาชีพอิสระ", idx: 19 },
{ text: "กลุ่มอื่นๆ", idx: 20 },
// { text: "Real-Time" },
// { text: "Audience" },
],
items: [],
};
},
methods: {
submit() {
let dataOption = [...this.option1, ...this.option2];
const filterOpt = dataOption.map((item) => {
return {
opinionId: item.opinionId,
choice: item.choice,
};
});
const filterOpt2 = filterOpt.filter((item) => item.choice !== null);
if (filterOpt2.length) {
this.payload.opinions = filterOpt2;
}
// console.log("opppp", filterOpt, filterOpt2);
// let payload = {
// firstName: "ธรรมนูญ",
// lastName: "สังขวรรณ",
// title: "",
// cid: "1189900247580",
// age: 60,
// phone: "0819444825",
// public_phone: "0819444885",
// facebook: "https://m.facebook.com/ThoThamanoon?mibextid=LQQJ4d",
// twitter: "ThoThamanoon",
// tiktok: "ThoThamanoon",
// otherSocial: "thamanoon.sun@gmail.com",
// image: null,
// email: null,
// job: "ผู้จัดการทั่วไปพัฒนาเครือข่ายผู้จำหน่าย บริษัท นิสสัน มอเตอร์",
// education: "ปริญญาเอก",
// vision: "เขียนรัฐธรรมนูญใหม่ “ทั้งฉบับ”",
// reason: "ให้มีสภาร่างรัฐธรรมนูญ (สสร.) ใหม่ จากการเลือกตั้ง100%",
// group: 7,
// zone: 1034,
// province: 10,
// // opinions: [
// // {
// // opinionId: "",
// // choice: "",
// // },
// // ],
// };
// console.log("this.payload", this.payload);
client.user.createUser
.mutate(this.payload)
.then((data) => {
console.log("data", data);
alert("บันทึกข้อมูลสำเร็จ");
this.$router.push("/upload");
// this.provinceItems = data;
})
.catch((error) => {
alert("ไม่สามารถอัปโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
},
Preview_image() {
console.log("this.image", this.image,this.image.length);
if (this.image) {
this.url = URL.createObjectURL(this.image);
// console.log('this.image', this.image)
if (this.image && this.image !== null) {
const reader = new FileReader();
reader.onload = (event) => {
console.log(event.target.result);
this.url = event.target.result;
};
reader.readAsDataURL(this.image);
console.log();
} else {
this.url = null;
}
},
filterData() {
// กรองข้อมูลอันที่สองโดยใช้ข้อมูลจากอันแรก
if (this.province && this.province.provinceCode) {
this.districtItems = [...Districts].filter(
(item) => item.provinceCode === this.province.provinceCode
);
}
// if (this.province && this.province.provinceCode) {
// this.districtItems = [...Districts].filter(
// (item) => item.provinceCode === this.province.provinceCode
// );
// }
this.payload.zone = null;
client.info.getAllZones
.query({ provice_id: this.payload.province })
.then((data) => {
this.districtItems = data;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
},
},
mounted() {
client.info.getAllOpinions
.query({ type: "3Choice" })
.then((rs) => {
let data = [...rs].map((x) => {
x.choice = null;
x.opinionId = x.id;
return x;
});
let data1 = [...data].filter((x) => x.type == "3Choice");
this.option1 = data1;
let data2 = [...data].filter((x) => x.type == "4Choice");
this.option2 = data2;
console.log("rs", rs, data1, data2);
})
.catch((error) => {
// alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
client.info.getAllGroups
.query({})
.then((groups) => {
this.items = groups;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
client.info.getAllProvinces
.query({})
.then((data) => {
this.provinceItems = data;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
},
};
</script>
<style>
.btn-next {
padding: 1.5rem 0 0;
}
.v-selection-control-group--inline > * {
flex-grow: 1;
}

View File

@@ -9,15 +9,21 @@
"
class="pa-lg-10 pa-md-10 pa-sm-4 pa-2"
>
<!-- {{ dataProfile }} -->
<v-row >
<v-col v-for="(item, i) in profile" :key="i" cols="12" md="6" lg="6" >
<v-col
v-for="(item, i) in dataProfile"
:key="i"
cols="12"
md="6"
lg="6"
>
<v-card elevation="5" class="text-sub2 mx-auto pb-5 card-user">
<div
style="background: #37332f; color: white; width: 100%"
class="font-weight-bold pa-2 w-100 text-center"
>
<div class="more">{{ item.group }}</div>
<div class="more" v-if="item.group">{{ item.group.name }}</div>
</div>
<v-card-item>
<v-row align="left">
@@ -28,28 +34,37 @@
</div> -->
<v-col cols="12" md="auto" class="text-center">
<v-avatar color="#635d56" size="100">
<v-icon
icon="mdi-account"
color=""
size="80"
></v-icon> </v-avatar
></v-col>
<!-- {{ item.image }} -->
<v-avatar
color="#635d56"
size="100"
v-if="item.image"
:image="item.image"
>
</v-avatar
><v-avatar color="#635d56" size="100" v-else>
<v-icon icon="mdi-account" color="" size="80"></v-icon>
</v-avatar>
</v-col>
<v-col cols="12" md="" class="text-center">
<div class="font-weight-bold text-normal my-2 text-center">
{{ item.name }}
{{ item.firstName }}
<span class="ml-3">
{{ item.lastname }}
{{ item.lastName }}
<span v-if="item.age" class="text-sub2">
( {{ item.age }}ปี )</span
></span
>
<div class="box-province px-3 py-2 text-sub2">
<div class="font-weight-bold">
{{ item.province }} |
<span class="font-weight-medium"
>เขต{{ item.district }}</span
<div
class="box-province px-3 py-2 text-sub2"
v-if="item.zone"
>
<div class="font-weight-bold">
{{ item.zone.province.name }} |
<span class="font-weight-medium">{{
item.zone.name
}}</span>
</div>
</div>
<!-- <div class="text-sub3">{{ item.group }}</div> -->
@@ -62,7 +77,7 @@
<div class="text-small text-left">
<div class="font-weight-medium">
<span class="font-weight-bold">อาช :</span>
{{ item.occupation }}
{{ item.job }}
</div>
<div class="font-weight-medium">
<span class="font-weight-bold">การศกษา :</span>
@@ -74,27 +89,60 @@
<div class="text-left text-small my-3">
<div class="text-small font-weight-bold">องทางตดต</div>
<v-divider class="my-1"></v-divider>
<span>
<span v-if="item.social.email" class="mr-2"
><v-icon icon="mdi-email"></v-icon>
{{ item.social.email }}</span
<div class="mt-2 d-flex justify">
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="23"
height="23"
viewBox="0 0 50 50"
class="mr-2"
>
<span v-if="item.social.fb" class="mr-2"
><v-icon icon="mdi-facebook"></v-icon>
{{ item.social.fb }}</span
<path
d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M37,19h-2c-2.14,0-3,0.5-3,2 v3h5l-1,5h-4v15h-5V29h-4v-5h4v-3c0-4,2-7,6-7c2.9,0,4,1,4,1V19z"
></path></svg
><span v-if="item.facebook"> {{ item.facebook }}</span
><span v-else> - </span>
</div>
<div class="mt-2 d-flex justify">
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="-5px"
width="23"
height="23"
viewBox="0 0 50 50"
class="mr-2"
>
<span v-if="item.social.x" class="mr-2"
><v-icon icon="mdi-twitter"></v-icon>
{{ item.social.x }}</span
>
<span v-if="item.phone" class="mr-2 d-none"
><v-icon icon="mdi-cellphone"></v-icon>
{{ item.phone }}</span
>
</span>
<path
d="M 11 4 C 7.134 4 4 7.134 4 11 L 4 39 C 4 42.866 7.134 46 11 46 L 39 46 C 42.866 46 46 42.866 46 39 L 46 11 C 46 7.134 42.866 4 39 4 L 11 4 z M 13.085938 13 L 21.023438 13 L 26.660156 21.009766 L 33.5 13 L 36 13 L 27.789062 22.613281 L 37.914062 37 L 29.978516 37 L 23.4375 27.707031 L 15.5 37 L 13 37 L 22.308594 26.103516 L 13.085938 13 z M 16.914062 15 L 31.021484 35 L 34.085938 35 L 19.978516 15 L 16.914062 15 z"
></path></svg
><span v-if="item.twitter"> {{ item.twitter }}</span
><span v-else> - </span>
</div>
<div class="text-small font-weight-bold text-left d-none">
<div class="mt-2 d-flex justify">
<!-- <i class="far fa-tiktok"></i> -->
<svg
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="23"
height="23"
viewBox="0 0 50 50"
class="mr-2"
>
<path
d="M41,4H9C6.243,4,4,6.243,4,9v32c0,2.757,2.243,5,5,5h32c2.757,0,5-2.243,5-5V9C46,6.243,43.757,4,41,4z M37.006,22.323 c-0.227,0.021-0.457,0.035-0.69,0.035c-2.623,0-4.928-1.349-6.269-3.388c0,5.349,0,11.435,0,11.537c0,4.709-3.818,8.527-8.527,8.527 s-8.527-3.818-8.527-8.527s3.818-8.527,8.527-8.527c0.178,0,0.352,0.016,0.527,0.027v4.202c-0.175-0.021-0.347-0.053-0.527-0.053 c-2.404,0-4.352,1.948-4.352,4.352s1.948,4.352,4.352,4.352s4.527-1.894,4.527-4.298c0-0.095,0.042-19.594,0.042-19.594h4.016 c0.378,3.591,3.277,6.425,6.901,6.685V22.323z"
></path></svg
><span v-if="item.tiktok"> {{ item.tiktok }}</span
><span v-else> - </span>
</div>
</div>
<!-- <div class="text-small font-weight-bold text-left d-none">
ดย
<v-divider class="my-1"></v-divider>
<v-row class="text-small" style="height: 150px; overflow: auto">
@@ -111,16 +159,23 @@
</div>
</v-col>
</v-row>
</div>
</div> -->
</v-card-item>
</v-card></v-col
>
</v-row>
<!-- {{ dataProfile.length }}
<div v-if="dataProfile.length == 0">ไม่พบข้อมูล</div> -->
</div>
</div>
</template>
<script>
export default {
props: {
dataProfile: {
type: Array,
},
},
data() {
return {
profile: [
@@ -297,7 +352,7 @@ export default {
</script>
<style>
.card-user {
height: auto;
height: 100%;
/* height: 370px; */
}
.more {

View File

@@ -12,11 +12,12 @@
<v-row>
<v-col cols="12" md="3">
<v-autocomplete
clearable
label="จังหวัด"
:items="provinceItems"
variant="solo"
item-title="provinceNameTh"
return-object
item-title="name"
item-value="id"
v-model="province"
placeholder="จังหวัด"
@update:modelValue="filterData"
@@ -25,25 +26,29 @@
></v-col>
<v-col cols="12" md="3">
<v-autocomplete
clearable
label="อำเภอ / เขต"
:items="districtItems"
variant="solo"
item-title="districtNameTh"
return-object
item-title="name"
v-model="district"
item-value="id"
placeholder="อำเภอ / เขต"
hide-details
:disabled="province == null"
></v-autocomplete
></v-col>
<v-col cols="12" md="3">
<v-autocomplete
clearable
label="กลุ่มอาชีพ"
:items="items"
variant="solo"
item-title="text"
return-object
item-title="name"
item-value="id"
placeholder="กลุ่มอาชีพ"
hide-details
v-model="group"
></v-autocomplete>
</v-col>
<v-col cols="12" md="3">
@@ -54,74 +59,144 @@
></v-text-field>
</v-col>
</v-row>
<v-btn color="#DD6C31" class="mt-8" elevated size="large">
<v-btn
color="#DD6C31"
class="mt-8"
elevated
size="large"
@click="searchUser(0)"
:loading="load"
>
<span class="text-sub">นหา</span>
</v-btn>
</v-container>
<ResultMain />
<!-- {{result}} -->
<CardUser :dataProfile="result" v-if="result.length" />
<!-- {{ show }} -->
<div
v-if="result.length == 0 && this.show"
class="my-10 text-sub2 txt-black"
>
<v-icon icon="mdi-alert-circle"></v-icon> ไมพบขอม
</div>
<div class="text-center">
<v-pagination
v-model="page"
:length="result.length / 10"
rounded="circle"
@click="searchUser((this.page - 1) * 10)"
></v-pagination>
</div>
</div>
</div>
</template>
<script>
import Provinces from "@/components/form/provinces.json";
import Districts from "@/components/form/districts.json";
import ResultMain from "./ResultMain.vue";
// import Provinces from "@/components/form/provinces.json";
// import Districts from "@/components/form/districts.json";
import CardUser from "./CardUser.vue";
import { client } from "@/utils/trpc";
export default {
components: {
ResultMain,
CardUser,
},
data() {
return {
show: false,
load: false,
result: [],
page: 1,
province: null,
district: null,
districtItems: [],
provinceItems: Provinces,
items: [
{ text: "กลุ่มบริหารราชการแผ่นดินและความมั่นคง", idx: 1 },
{ text: "กลุ่มกฎหมายกระบวนการยุติธรรม", idx: 2 },
{ text: "กลุ่มการศึกษา", idx: 3 },
{ text: "กลุ่มการสาธารณสุข", idx: 4 },
{ text: "กลุ่มอาชีพทำนา ปลูกพืชล้มลุก", idx: 5 },
{ text: "กลุ่มอาชีพทำสวน ป่าไม้ ปศุสัตว์ ประมง", idx: 6 },
{ text: "กลุ่มพนักงานหรือลูกจ้างของบุคคล(ไม่ใช่หน่วยงานรัฐ)", idx: 7 },
{
text: "กลุ่มผู้ประกอบอาชีพด้านสิ่งแวดล้อม ผังเมือง อสังหาริมทรัพย์และสาธารณูปโภค ทรัพยากรธรรมชาติ พลังงาน",
idx: 8,
},
{ text: "กลุ่มผู้ประกอบกิจการ หรือ SME", idx: 9 },
{ text: "กลุ่มผู้ประกอบกิจการอื่นนอกจากข้อ (9)", idx: 10 },
{ text: "กลุ่มผู้ประกอบธุรกิจหรืออาชีพด้านการท่องเที่ยว", idx: 11 },
{ text: "กลุ่มผู้ประกอบอุตสาหกรรม", idx: 12 },
{
text: "กลุมผู้ประกอบอาชีพด้านวิทยาศาสตร์ เทคโนโลยี การสื่อสาร การพัฒนานวัตรกรรม",
idx: 13,
},
{ text: "กลุ่มสตรี", idx: 14 },
{
text: "กลุ่มผู้สูงอายุ คนพิการหรือทุพพลภาพ กลุ่มชาติพันธุ์ กลุ่มอัตลักษณ์อื่น",
idx: 15,
},
{ text: "กลุ่มศิลปะ วัฒนธรรม ดนตรี การแสดงและบันเทิง", idx: 16 },
{ text: "กลุ่มประชาสังคม องค์กรสาธารณประโยชน์", idx: 17 },
{ text: "กลุ่มนักกีฬา สื่อสารมวลชน ผู้สร้างสรรค์วรรณกรรม", idx: 18 },
{ text: "กลุ่มผู้ประกอบวิชาชีพ ผู้ประกอบอาชีพอิสระ", idx: 19 },
{ text: "กลุ่มอื่นๆ", idx: 20 },
// { text: "Real-Time" },
// { text: "Audience" },
],
provinceItems: [],
items: [],
group: null,
offset: 0,
};
},
methods: {
searchUser(offset) {
this.show = false;
this.load = true;
if (offset == 0) {
this.page = 1;
}
// this.offset = (this.page - 1) * 10;
let data = {
offset: offset,
limit: 10,
// group: this.group,
// zone: this.district,
};
if (this.group) {
data.group = this.group;
}
if (this.district) {
data.zone = this.district;
}
// for (const key in data) {
// if (data[key] === null) {
// delete data[key];
// }
// }
console.log(data);
client.user.getAllUser
.query(data)
.then((rs) => {
this.result = rs;
console.log(rs);
this.load = false;
if (rs.length == 0) {
this.show = true;
}
// this.districtItems = rs;
})
.catch((error) => {
this.load = false;
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
},
filterData() {
// กรองข้อมูลอันที่สองโดยใช้ข้อมูลจากอันแรก
if (this.province && this.province.provinceCode) {
this.districtItems = [...Districts].filter(
(item) => item.provinceCode === this.province.provinceCode
);
this.district = null;
if (this.province) {
client.info.getAllZones
.query({ provice_id: this.province })
.then((data) => {
this.districtItems = data;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
}
},
},
mounted() {
client.info.getAllGroups
.query({})
.then((groups) => {
this.items = groups;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
client.info.getAllProvinces
.query({})
.then((data) => {
this.provinceItems = data;
})
.catch((error) => {
alert("ไม่สามารถโหลดข้อมูลได้");
console.error("เกิดข้อผิดพลาดในการโหลดข้อมูล:", error);
});
},
};
</script>
<style></style>

View File

@@ -4,6 +4,8 @@ export default createStore({
state: {},
getters: {},
mutations: {},
actions: {},
actions: {
},
modules: {},
});

View File

@@ -1,25 +1,100 @@
<template>
<div>
<input
<div
style="background: #b2c573"
class="mt-5 d-flex justify-center parent-container py-10"
>
<!-- <input
type="file"
@change="onFileChanged($event)"
accept="image/*"
capture
/>
<button @click="uploadImage()">Upload</button>
<button @click="uploadImage()">Upload</button> -->
<v-row align="center" justify="center">
<v-col cols="12" md="8">
<v-card color="#4C884C" class="pa-5 text-center h-100" elevated>
<div class="text-sub text-left">
<v-icon icon="mdi-plus-box-multiple"></v-icon>
เพมรปภาพ
</div>
<!-- {{url}} -->
<v-avatar size="200" color="grey" class="elevation-3">
<v-img :src="url" v-if="url"></v-img>
<v-icon dark v-else size="80"> mdi-account </v-icon>
</v-avatar>
<v-file-input
label="แนบรูปภาพ"
accept="image/png, image/jpeg, image/bmp"
placeholder="แนบรูปภาพไฟล์ png/jpeg/jpg"
prepend-inner-icon="mdi-camera"
prepend-icon=""
variant="solo-filled"
class="mt-5"
v-model="image"
@change="onFileChanged($event)"
></v-file-input>
<v-btn
color="#DD6C31"
class="mt-4"
height="40"
@click="uploadImage()"
:disabled="image == null"
>
<span class="text-sub2">upload</span>
</v-btn>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { client } from "@/utils/trpc";
import { createFormData } from "@/utils/fileUpload";
export default {
watch: {
image(val) {
console.log(val);
if (val == undefined) {
this.url = null;
this.image = null;
}
},
},
data: () => ({
file: null,
url: null,
image: null,
}),
methods: {
Preview_image() {
// console.log('this.image', this.image)
if (this.image && this.image !== null) {
const reader = new FileReader();
reader.onload = (event) => {
console.log(event.target.result);
this.url = event.target.result;
};
reader.readAsDataURL(this.image);
console.log();
} else {
this.url = null;
}
},
onFileChanged(event) {
const file = event.target.files[0];
this.file = file;
if (this.file && this.file !== null) {
const reader = new FileReader();
reader.onload = (event) => {
console.log(event.target.result);
this.url = event.target.result;
};
reader.readAsDataURL(this.file);
console.log();
} else {
this.url = null;
}
},
async uploadImage() {