Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/assets/icon/help-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions app/components/Tooltip.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<div class="relative inline-block">
<div
@mouseenter="showTooltip = true"
@mouseleave="showTooltip = false"
@focus="showTooltip = true"
@blur="showTooltip = false"
>
<slot />
</div>

<Transition
enter-active-class="transition-opacity duration-200"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition-opacity duration-200"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-if="showTooltip"
:class="[
'absolute z-50 whitespace-nowrap rounded-lg bg-gray-800 px-3 py-2 text-[16px] font-normal text-white shadow-lg',
'pointer-events-none',
positionClasses,
]"
>
{{ content }}
<div :class="['absolute h-2 w-2 rotate-45 bg-gray-800', arrowClasses]"></div>
</div>
</Transition>
</div>
</template>

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

interface Props {
content: string;
position?: "top" | "bottom" | "left" | "right";
}

const props = withDefaults(defineProps<Props>(), {
position: "top",
});

const showTooltip = ref(false);

const positionClasses = computed(() => {
switch (props.position) {
case "top":
return "bottom-full left-1/2 transform -translate-x-1/2 mb-2";
case "bottom":
return "top-full left-1/2 transform -translate-x-1/2 mt-2";
case "left":
return "right-full top-1/2 transform -translate-y-1/2 mr-2";
case "right":
return "left-full top-1/2 transform -translate-y-1/2 ml-2";
default:
return "bottom-full left-1/2 transform -translate-x-1/2 mb-2";
}
});

const arrowClasses = computed(() => {
switch (props.position) {
case "top":
return "top-full left-1/2 transform -translate-x-1/2 -mt-1";
case "bottom":
return "bottom-full left-1/2 transform -translate-x-1/2 -mb-1";
case "left":
return "left-full top-1/2 transform -translate-y-1/2 -ml-1";
case "right":
return "right-full top-1/2 transform -translate-y-1/2 -mr-1";
default:
return "top-full left-1/2 transform -translate-x-1/2 -mt-1";
}
});
</script>
19 changes: 16 additions & 3 deletions app/pages/analyze/_components/FormPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useForm } from "@tanstack/vue-form";
import { useFileStore } from "~/stores/file";
import { formSchema } from "../_utils/formSchema";
import type z from "zod";
import HelpCircle from "~/assets/icon/help-circle.svg";

const fileStore = useFileStore();

Expand Down Expand Up @@ -92,7 +93,7 @@ const emit = defineEmits<{
<button
type="button"
:class="[
'rounded-[10px] border border-primary px-[100px] py-[30px] text-center text-[26px] font-[400] text-primary transition-colors',
'rounded-[10px] border border-primary px-[100px] py-[24px] text-center text-[26px] font-[400] text-primary transition-colors',
field.state.value === '전세' ? 'border-2 bg-secondary font-[600]' : 'border-1',
]"
@click="field.handleChange('전세')"
Expand All @@ -102,7 +103,7 @@ const emit = defineEmits<{
<button
type="button"
:class="[
'rounded-[10px] border border-primary px-[100px] py-[30px] text-center text-[26px] font-[400] text-primary transition-colors',
'rounded-[10px] border border-primary px-[100px] py-[24px] text-center text-[26px] font-[400] text-primary transition-colors',
field.state.value === '월세' ? 'border-2 bg-secondary font-[600]' : 'border-1',
]"
@click="field.handleChange('월세')"
Expand All @@ -116,7 +117,19 @@ const emit = defineEmits<{

<!-- 2. 보증금 입력 -->
<div>
<span class="text-[26px] font-[400] text-foreground">2. 보증금 입력</span>
<span class="inline-flex items-center gap-2 text-[26px] font-[400] text-foreground">
2. 보증금 입력
<Tooltip
content="보증금은 안전지수 분석에 활용되므로, 해당 매물의 실제 금액을 정확히 입력해 주세요."
position="top"
>
<HelpCircle
class="h-[16px] w-[16px] cursor-help text-primary"
:font-controlled="false"
filled="false"
/>
</Tooltip>
</span>
<div class="mt-4 flex items-center justify-between gap-[15px]">
<form.Field name="deposit_hundred_million">
<template #default="{ field }">
Expand Down
4 changes: 4 additions & 0 deletions app/pages/analyze/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { apiInstance, type BaseResponse } from "~/utils/api";
import { useModalStore } from "~/stores/modal";
import PdfSubmitted from "./_modals/PdfSubmitted.vue";

useHead({
title: "등기부등본 분석하기",
});

const modalStore = useModalStore();

const { mutate: submit } = useMutation<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import ChevronRightBlue from "~/assets/icon/chevron-right-blue.svg";
<!-- 절차 -->
<div class="flex justify-center gap-[60px] py-[60px]">
<!-- Step 1 -->
<ProcessStep :step="1" title="등본 업로드">
<ProcessStep :step="1" title="전처리">
<template #icon>
<AnalysisStep1 class="h-[180px] w-[180px]" :font-controlled="false" filled="false" />
</template>
<template #description>
업로드 한 등본을
업로드 한 등기부등본을
<br />
AI가 분석합니다.
전처리 후, AI가 분석을 시작합니다.
</template>
</ProcessStep>
<ChevronRightBlue
Expand All @@ -37,7 +37,7 @@ import ChevronRightBlue from "~/assets/icon/chevron-right-blue.svg";
<AnalysisStep2 class="h-[180px] w-[180px]" :font-controlled="false" filled="false" />
</template>
<template #description>
등본에서 뭐뭐를 추출, 무엇의 기준을 바탕으로 등본을 계산하여 분석을 진행합니다.
등기부등본에서 텍스트를 추출하고, 공인된 기준들을 바탕으로 분석을 진행합니다.
</template>
</ProcessStep>
<ChevronRightBlue
Expand All @@ -51,7 +51,7 @@ import ChevronRightBlue from "~/assets/icon/chevron-right-blue.svg";
<AnalysisStep3 class="h-[180px] w-[180px]" :font-controlled="false" filled="false" />
</template>
<template #description>
안전도를 분석하여 위험도 점수를 도출합니다.
자체 연구하여 도출한 검증된 안전지수 공식을 바탕으로 위험도 점수를 계산합니다.
<br />
<br />
0-2점: 위험
Expand All @@ -71,7 +71,7 @@ import ChevronRightBlue from "~/assets/icon/chevron-right-blue.svg";
<template #icon>
<AnalysisStep4 class="h-[180px] w-[180px]" :font-controlled="false" filled="false" />
</template>
<template #description>AI가 종합하여 최종 결과를 자세히 내보냅니다.</template>
<template #description>AI가 분석 결과를 종합하여 최종 결과를 내보냅니다.</template>
</ProcessStep>
</div>

Expand All @@ -82,13 +82,17 @@ import ChevronRightBlue from "~/assets/icon/chevron-right-blue.svg";
>
<img src="~/assets/image/alien.png" alt="셋방살이" class="h-auto w-[130px]" />
<span class="mt-[30px] text-[24px] font-[600] text-primary">
셋방살이는 (공공기관 이름)의 가이드를 바탕으로 근거를 수립했습니다.
셋방살이는 공공기관의 자료와 전문가의 가이드를 바탕으로 근거를 수립했습니다.
</span>
<span class="mt-[15px] text-[20px] font-[500] text-gray-66">
더 자세한 내용은 (공공기관 이름 또는 우리 노션)을 참고해주세요.
더 자세한 내용은
<a href="https://www.khug.or.kr/index.jsp" target="_blank" class="text-primary">
HUG 주택도시보증공사
</a>
를 참고해주세요.
</span>
<p class="mt-[25px] text-[20px] font-[500] text-gray-66">
AI가 분석한 내용은 실제와 다를 수 있으니 확인용도로만 이용 부탁드립니다.
<p class="mt-[25px] text-[16px] font-[500] text-gray-66">
AI가 분석한 내용은 실제와 다를 수 있으며,
<br />
AI 분석 결과로 인한 문제 발생 시 법적 책임은 본인에게 있음을 알려드립니다.
</p>
Expand Down
5 changes: 5 additions & 0 deletions app/pages/analyze/result/[reportId]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { useQuery } from "@tanstack/vue-query";
import ProcessAndDisclaimer from "./_components/ProcessAndDisclaimer.vue";
import { apiInstance } from "~/utils/api";
import type { AnalyzeResultResponse } from "./_api/types/AnalyzeResultResponse";
import { useHead } from "#app";

useHead({
title: "분석 결과",
});

const reportId = useRoute().params.reportId;

Expand Down
6 changes: 5 additions & 1 deletion app/pages/checklist/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
class="h-[64px] w-[177px] justify-start rounded-[10px] bg-primary text-[28px] font-[500] text-background"
@click="gotoQuiz"
>
퀴즈풀기
퀴즈 풀기
</button>
</div>
<div class="mt-[90px] flex w-[896px] flex-col">
Expand Down Expand Up @@ -184,6 +184,10 @@ import Five from "~/assets/image/checkFive.jpg";
import CheckCard from "./_components/CheckCard.vue";
import CheckTipBox from "./_components/CheckTipBox.vue";

useHead({
title: "체크리스트",
});

const gotoQuiz = () => {
navigateTo("/quiz");
};
Expand Down
25 changes: 15 additions & 10 deletions app/pages/community/_components/CommentWrap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,22 @@
</div>
</div>

<div v-if="PostModalOpen" class="fixed inset-0 z-50 flex items-center justify-center">
<div class="absolute inset-0 bg-zinc-900/40" @click="handlePostModal"></div>
<div class="z-60 relative">
<PostComment
:road-code="roadCode"
:building-number="buildingNumber"
:selected-address="selectedAddress"
@close="handlePostModal"
/>
<Teleport to="body">
<div
v-if="PostModalOpen"
class="fixed inset-0 z-[9999] flex items-center justify-center bg-gray-1a/40"
>
<div class="absolute inset-0" @click="handlePostModal"></div>
<div class="relative">
<PostComment
:road-code="roadCode"
:building-number="buildingNumber"
:selected-address="selectedAddress"
@close="handlePostModal"
/>
</div>
</div>
</div>
</Teleport>
</div>
</template>

Expand Down
19 changes: 17 additions & 2 deletions app/pages/community/_components/SearchBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,32 @@

<script setup lang="ts">
import BlueSearch from "~/assets/icon/blueSearchIcon.svg";
import { ref, defineEmits, computed } from "vue";
import { ref, defineEmits, computed, defineProps, watch } from "vue";
import { useQuery } from "@tanstack/vue-query";
import { apiInstance } from "~/utils/api";
import type { BaseResponse } from "~/utils/api";
import type { SearchAddressResponse } from "../_api/types/SearchAddressResponse";
import { useDebounce } from "~/composables/useDebounce";
import { splitByKeyword } from "../_utils/splitByKeyword";

const address = ref("");
const props = defineProps<{
initialValue?: string;
}>();

const address = ref(props.initialValue || "");
const debouncedAddress = useDebounce(address, 500);

// Watch for changes in initialValue prop
watch(
() => props.initialValue,
(newValue) => {
if (newValue) {
address.value = newValue;
}
},
{ immediate: true }
);

const emits = defineEmits(["search-address"]);

const { data: searchResponse } = useQuery<BaseResponse<SearchAddressResponse>>({
Expand Down
15 changes: 14 additions & 1 deletion app/pages/community/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
id="map"
class="absolute left-[598px] top-0 z-10 h-[871px] w-[897px] rounded-[20px] bg-gray-1a"
>
<SearchBar @search-address="searchAddress"></SearchBar>
<SearchBar :initial-value="selectedAddress" @search-address="searchAddress"></SearchBar>
</div>
</div>
</template>
Expand All @@ -80,6 +80,10 @@ import CreditStore from "../credit/creditStore.vue";
import { useQuery } from "@tanstack/vue-query";
import { apiInstance } from "~/utils/api";

useHead({
title: "커뮤니티",
});

const currentTab = ref("community");
const handleTabStore = () => {
currentTab.value = "store";
Expand Down Expand Up @@ -196,6 +200,15 @@ onMounted(async () => {

// 초기 로드 시 네비바에서 검색해서 온 경우 처리
handleNavbarSearch();

// 페이지 마운트 시 기본 주소로 검색
selectedAddress.value = "서울특별시 성북구 동소문로26나길 19";

searchAddress({
buldMnnm: "19",
rnMgtSn: "112904121104",
roadAddrPart1: "서울특별시 성북구 동소문로26나길 19",
});
});

const searchAddress = (suggestion) => {
Expand Down
6 changes: 5 additions & 1 deletion app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { ref, onMounted, onUnmounted } from "vue";

useHead({
title: "전월세 피해 예방 플랫폼",
});

gsap.registerPlugin(ScrollTrigger);

// Refs for elements
Expand Down Expand Up @@ -285,7 +289,7 @@ onUnmounted(() => {

<!-- 가격 -->
<div ref="pricingSection">
<PricingPage />
<PricingPage :is-embedded="true" />
</div>
</section>
</main>
Expand Down
6 changes: 5 additions & 1 deletion app/pages/my/_components/AnalysisPreviewCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const props = defineProps<{
address: string;
safetyScore: number;
safetyDescription: string;
reportId: number;
}>();
</script>

Expand All @@ -29,7 +30,10 @@ const props = defineProps<{
{{ props.safetyDescription }}
</p>
</div>
<span class="flex cursor-pointer items-center gap-2 text-[20px] font-[400] text-gray-b4">
<span
class="flex cursor-pointer items-center gap-2 text-[20px] font-[400] text-gray-b4"
@click="navigateTo(`/analyze/result/${props.reportId}`)"
>
자세히 보기
<RightArrowGrayIcon class="h-[10px]" :font-controlled="false" filled="false" />
</span>
Expand Down
1 change: 1 addition & 0 deletions app/pages/my/_components/MyCredit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</div>
<button
class="ml-auto rounded-[10px] bg-primary px-[40px] py-[10px] text-[28px] font-[600] text-gray-fe"
@click="navigateTo('/community?tab=store')"
>
크레딧 사용 제휴처 확인
</button>
Expand Down
Loading