64 lines
1.8 KiB
Vue
64 lines
1.8 KiB
Vue
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { generateMotto as generateMottoApi } from '../lib/api';
|
|
import { useAuthStore } from '../stores/auth';
|
|
import VueHcaptcha from '@hcaptcha/vue3-hcaptcha';
|
|
|
|
const motto = ref('');
|
|
const mottoLoading = ref(false);
|
|
const hcaptchaResponse = ref('');
|
|
|
|
const authStore = useAuthStore();
|
|
|
|
const hcaptchaRef = ref(null);
|
|
|
|
const handleHcaptchaVerify = (token) => {
|
|
hcaptchaResponse.value = token;
|
|
};
|
|
|
|
const handleHcaptchaExpired = () => {
|
|
hcaptchaResponse.value = '';
|
|
};
|
|
|
|
const generateMotto = async () => {
|
|
mottoLoading.value = true;
|
|
|
|
try {
|
|
const generatedMotto = await generateMottoApi(authStore.jwt, hcaptchaResponse.value);
|
|
motto.value = generatedMotto;
|
|
hcaptchaRef.value.reset();
|
|
} catch (error) {
|
|
console.error(error);
|
|
alert('Failed to generate motto.');
|
|
}
|
|
|
|
mottoLoading.value = false;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="ts-app-center">
|
|
<div>
|
|
<div class="ts-box ts-content is-center-aligned">
|
|
<div class="ts-header is-large is-center-aligned">每日金句生成器</div>
|
|
<div class="ts-header is-secondary is-center-aligned">Powered By Cloudflare Workers AI</div>
|
|
<VueHcaptcha
|
|
ref="hcaptchaRef"
|
|
:sitekey="$hcaptchaSitekey"
|
|
@verify="handleHcaptchaVerify"
|
|
@expired="handleHcaptchaExpired"
|
|
@reset="handleHcaptchaExpired"
|
|
/>
|
|
<button class="ts-button" @click="generateMotto" :disabled="!hcaptchaResponse">生成</button>
|
|
</div>
|
|
<div class="ts-content is-center-aligned">
|
|
<p class="ts-text">每日金句:</p>
|
|
<div class="ts-loading" v-if="mottoLoading"></div>
|
|
<div class="ts-quote" v-if="motto">
|
|
<p class="ts-text">{{ motto }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|