25
25
<p v-show =" status" class =" mt-2 text-red-600" >{{ status }}</p >
26
26
</div >
27
27
<div v-show =" application.code" class =" max-w-md mx-3 my-5 py-4 px-8 bg-white shadow-lg rounded-lg" >
28
- <h2 class =" text-gray-800 text-3xl font-semibold" >
28
+ <h2 class =" text-gray-800 text-3xl font-semibold mb-3 " >
29
29
加入代碼:{{ application.code }}
30
30
</h2 >
31
31
<p class =" mt-2 text-gray-600" >
32
- 使用者代碼:{{ application.user_agent }}<br />
33
- IP 位址:{{ application.ip_address }}<br />
34
- 申請時間:{{ new Date(application.created_at * 1000) }}
32
+ <ul class =" mb-3" >
33
+ <li >申請時間:{{ dateParsedCreatedAt }}</li >
34
+ </ul >
35
+ <ul class =" mb-3" >
36
+ <li >IP 位址:{{ application.ip_address }}</li >
37
+ <li >IP 地理資訊:
38
+ <ul class =" pl-3" >
39
+ <li >國家:{{ application.ip_geolocation.country }}</li >
40
+ <li >城市:{{ application.ip_geolocation.city }}</li >
41
+ <li >時區:{{ application.ip_geolocation.timezone }}</li >
42
+ </ul >
43
+ </li >
44
+ </ul >
45
+ <ul class =" mb-3" >
46
+ <li >使用者裝置資訊:
47
+ <ul class =" pl-3" >
48
+ <li >作業系統:
49
+ <ul class =" pl-3" >
50
+ <li >名稱:{{ uaParsed.os.name }}</li >
51
+ <li >版本:{{ uaParsed.os.version }}</li >
52
+ </ul >
53
+ </li >
54
+ <li >瀏覽器:
55
+ <ul class =" pl-3" >
56
+ <li >名稱:{{ uaParsed.browser.name }}</li >
57
+ <li >版本:{{ uaParsed.browser.version }}</li >
58
+ <li >使用者代理:
59
+ <p class =" pl-3" >
60
+ <code >{{ uaParsed.ua }}</code >
61
+ </p >
62
+ </li >
63
+ </ul >
64
+ </li >
65
+ </ul >
66
+ </li >
67
+ </ul >
35
68
</p >
36
69
<div v-if =" !application.approval_by" class =" flex justify-end mt-4" >
37
70
<button
46
79
</button >
47
80
</div >
48
81
<p v-else class =" mt-2 text-amber-600" >
49
- 已由 {{ application.approval_by }} 於 {{ new Date(application.approval_at * 1000) }} 許可
82
+ 已由 {{ application.approval_by }} 於 {{ dateParsedApprovalAt }} 許可
50
83
</p >
51
84
</div >
52
85
</div >
53
86
</div >
54
87
</template >
55
88
56
89
<script >
90
+ import uaParser from " ua-parser-js" ;
91
+
92
+ import dayjs from " dayjs" ;
93
+ import dayjsUtc from " dayjs/plugin/utc" ;
94
+ import dayjsTimezone from " dayjs/plugin/timezone" ;
95
+ import dayjsLocalizedFormat from " dayjs/plugin/localizedFormat" ;
96
+
97
+ dayjs .extend (dayjsUtc);
98
+ dayjs .extend (dayjsTimezone);
99
+ dayjs .extend (dayjsLocalizedFormat);
100
+
57
101
export default {
58
102
name: " AdminJoinView" ,
59
103
data : () => ({
@@ -64,6 +108,10 @@ export default {
64
108
application: {}
65
109
}),
66
110
methods: {
111
+ dateToHuman (timestamp ) {
112
+ const userTimezone = dayjs .tz .guess ();
113
+ return dayjs .tz (timestamp, userTimezone).format (" llll" );
114
+ },
67
115
async submit () {
68
116
this .status = ' ' ;
69
117
if (! this .query ) {
@@ -103,6 +151,30 @@ export default {
103
151
}
104
152
}
105
153
},
154
+ computed: {
155
+ uaParsed () {
156
+ const {
157
+ user_agent: uaString ,
158
+ } = this .application ;
159
+ return uaParser (uaString);
160
+ },
161
+ dateParsedCreatedAt () {
162
+ const {
163
+ created_at: createdAt ,
164
+ } = this .application ;
165
+ return this .dateToHuman (
166
+ createdAt * 1000 ,
167
+ );
168
+ },
169
+ dateParsedApprovalAt () {
170
+ const {
171
+ approval_at: approvalAt ,
172
+ } = this .application ;
173
+ return this .dateToHuman (
174
+ approvalAt * 1000 ,
175
+ );
176
+ },
177
+ },
106
178
async created () {
107
179
this .profile = await this .$profile ();
108
180
if (! this .profile ) {
0 commit comments