AIAssistantPanel.vue 4.55 KB
<template>
  <div class="ai-assistant-panel">
    <div class="settings-content-header">
      <h1>{{ $t("settings.aiAssistant.title") }}</h1>
      <p>{{ $t("settings.aiAssistant.desc") }}</p>
    </div>
    <div class="section section-model">
      <div class="section-title">
        {{ $t("settings.aiAssistant.modelTitle") }}
      </div>
      <div class="section-desc">{{ $t("settings.aiAssistant.modelDesc") }}</div>
      <div class="form-group">
        <select v-model="model" class="select">
          <option v-for="m in modelOptions" :key="m.value" :value="m.value">
            {{ m.label }}
          </option>
        </select>
      </div>
    </div>
    <div class="divider"></div>
    <div class="section section-length">
      <div class="section-title">
        {{ $t("settings.aiAssistant.lengthTitle") }}
      </div>
      <div class="section-desc">
        {{ $t("settings.aiAssistant.lengthDesc") }}
      </div>
      <div class="form-group length-row">
        <label
          v-for="opt in lengthOptions"
          :key="opt.value"
          class="radio-label"
        >
          <input type="radio" v-model="replyLength" :value="opt.value" />
          <span
            :class="['radio-custom', { checked: replyLength === opt.value }]"
          />
          <span class="radio-text">{{ opt.label }}</span>
        </label>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";

const { t } = useI18n();

interface ModelOption {
  value: string;
  label: string;
}

interface LengthOption {
  value: string;
  label: string;
}

const model = ref("gemini-pro");
const replyLength = ref("balanced");

const modelOptions: ModelOption[] = [
  { value: "gemini-pro", label: "Gemini Pro" },
  { value: "gpt-4", label: "GPT-4" },
  { value: "gpt-3.5", label: "GPT-3.5" },
];

const lengthOptions = computed<LengthOption[]>(() => [
  { value: "short", label: t("settings.aiAssistant.lengthShort") },
  { value: "balanced", label: t("settings.aiAssistant.lengthBalanced") },
  { value: "detailed", label: t("settings.aiAssistant.lengthDetailed") },
]);
</script>

<style scoped lang="scss">
.ai-assistant-panel {
  color: var(--color-text);
  background: var(--color-bg);
  max-width: 520px;
  margin-left: 0;
  margin-right: auto;
  padding: 0 0 40px 0;
}

.settings-content-header {
  margin-top: 24px;
  margin-bottom: 48px;
  text-align: left;

  h1 {
    font-size: 32px;
    font-weight: 800;
    color: var(--color-text);
    margin-bottom: 10px;
    letter-spacing: 1px;
  }

  p {
    font-size: 16px;
    color: var(--color-secondary);
    font-weight: 400;
  }
}

.section {
  width: 100%;
  margin-bottom: 56px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.section-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: 10px;
  text-align: left;
  letter-spacing: 1px;
}

.section-desc {
  font-size: 14px;
  color: var(--color-secondary);
  margin-bottom: 18px;
}

.form-group {
  margin-bottom: 0;
  width: 100%;
}

.select {
  background: var(--color-card);
  color: var(--color-text);
  border: 1.5px solid var(--color-border);
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 15px;
  outline: none;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 0;
  margin-top: 0;
  transition: border-color 0.2s;

  &:focus {
    border-color: var(--color-primary);
  }
}

.divider {
  width: calc(100% + 48px);
  height: 1px;
  background: var(--color-border);
  margin: 48px 0 56px -48px;
  opacity: 0.7;
  align-self: stretch;
}

.length-row {
  display: flex;
  align-items: center;
  gap: 32px;
  margin-top: 8px;
}

.radio-label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;

  input[type="radio"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
  }
}

.radio-custom {
  width: 18px;
  height: 18px;
  border: 2px solid var(--color-border);
  border-radius: 50%;
  position: relative;
  transition: all 0.2s;

  &.checked {
    border-color: #3399ff;

    &::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 10px;
      height: 10px;
      background: #3399ff;
      border-radius: 50%;
    }
  }
}

.radio-text {
  font-size: 15px;
  color: var(--color-text);
  font-weight: 500;
}

@media (max-width: 1024px) {
  .ai-assistant-panel {
    max-width: 100%;
    padding: 0 4px 20px 4px;
  }

  .length-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
}
</style>