탑뷰수정
All checks were successful
LocalNet_front/pipeline/head This commit looks good

This commit is contained in:
nevermoregb 2025-04-04 13:30:38 +09:00
parent 4907a12e65
commit daa3bb9921
2 changed files with 146 additions and 123 deletions

View File

@ -9,12 +9,7 @@
<!-- 날씨 정보 영역 --> <!-- 날씨 정보 영역 -->
<div class="navbar-nav align-items-center"> <div class="navbar-nav align-items-center">
<div class="d-flex align-items-center weather-box"> <div class="d-flex align-items-center weather-box">
<img <img v-if="weather.icon" :src="customIconUrl" :alt="weather.description" :class="customIconClass" />
v-if="weather.icon"
:src="customIconUrl"
:alt="weather.description"
:class="customIconClass"
/>
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<span class="weather-desc">{{ weather.description }}</span> <span class="weather-desc">{{ weather.description }}</span>
<span class="weather-temp" v-if="weather.tempMin !== null && weather.tempMax !== null"> <span class="weather-temp" v-if="weather.tempMin !== null && weather.tempMax !== null">
@ -268,6 +263,7 @@
import { useProjectStore } from '@/stores/useProjectStore'; import { useProjectStore } from '@/stores/useProjectStore';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useThemeStore } from '@s/darkmode'; import { useThemeStore } from '@s/darkmode';
import { useWeatherStore } from '@/stores/useWeatherStore';
import { computed, onMounted, ref, watch } from 'vue'; import { computed, onMounted, ref, watch } from 'vue';
import axios from '@api'; import axios from '@api';
@ -277,9 +273,12 @@
const userStore = useUserInfoStore(); const userStore = useUserInfoStore();
const projectStore = useProjectStore(); const projectStore = useProjectStore();
const router = useRouter(); const router = useRouter();
const weatherStore = useWeatherStore();
const user = ref(null); const user = ref(null);
const selectedProject = ref(null); const selectedProject = ref(null);
const weather = ref({});
const dailyWeatherList = ref([]);
// //
const myActiveProjects = computed(() => { const myActiveProjects = computed(() => {
@ -302,9 +301,7 @@
if (!selectedProject.value) return; if (!selectedProject.value) return;
// //
let selected = projectStore.activeProjectList.find( let selected = projectStore.activeProjectList.find(project => project.PROJCTSEQ === selectedProject.value);
project => project.PROJCTSEQ === selectedProject.value
);
if (selected) { if (selected) {
projectStore.setSelectedProject(selected); projectStore.setSelectedProject(selected);
@ -312,15 +309,42 @@
}; };
// //
watch(() => projectStore.selectedProject, (newProject) => { watch(
if (newProject) { () => projectStore.selectedProject,
selectedProject.value = newProject.PROJCTSEQ; newProject => {
} if (newProject) {
selectedProject.value = newProject.PROJCTSEQ;
}
},
);
const customIconUrl = computed(() => {
if (weather.value.icon === '01d' || weather.value.icon === '01n') {
return '/img/icons/sunny-custom.png';
}
return `https://openweathermap.org/img/wn/${weather.value.icon}@2x.png`;
}); });
const customIconClass = computed(() => {
if (weather.value.icon === '01d' || weather.value.icon === '01n') {
return 'custom-sunny-icon';
}
return 'weather-icon';
});
const weatherKorean = computed(() => weather.value.description || '날씨 정보 없음');
// const { isDarkMode, switchToDarkMode, switchToLightMode } = useThemeStore(); // const { isDarkMode, switchToDarkMode, switchToLightMode } = useThemeStore();
const handleLogout = async () => {
await authStore.logout();
router.push('/login');
};
const goToMyPage = () => {
router.push('/mypage');
};
onMounted(async () => { onMounted(async () => {
// if (isDarkMode) { // if (isDarkMode) {
// switchToDarkMode(); // switchToDarkMode();
@ -342,119 +366,47 @@
projectStore.setSelectedProject(firstProject); projectStore.setSelectedProject(firstProject);
} }
//
await weatherStore.getWeatherInfo();
weather.value = weatherStore.weather; //
dailyWeatherList.value = weatherStore.dailyWeatherList; //
}); });
const weather = ref({
icon: '',
description: '',
tempMin: null,
tempMax: null,
});
const customIconUrl = computed(() => {
if (weather.value.icon === "01d" || weather.value.icon === "01n") {
return "/img/icons/sunny-custom.png";
}
return `https://openweathermap.org/img/wn/${weather.value.icon}@2x.png`;
});
const customIconClass = computed(() => {
if (weather.value.icon === "01d" || weather.value.icon === "01n") {
return "custom-sunny-icon";
}
return "weather-icon";
});
const weatherKorean = computed(() => weather.value.description || '날씨 정보 없음');
onMounted(() => {
if (!userStore.user) return;
navigator.geolocation.getCurrentPosition(async (position) => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
try {
await userStore.userInfo();
const res = await axios.get(`/weather`, {
params: { lat, lon },
withCredentials: true,
});
const raw = res.data;
const data = JSON.parse(raw.data);
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
console.error('날씨 데이터 형식 오류 또는 없음:', data);
return;
}
const now = new Date();
const closest = data.list.reduce((prev, curr) => {
const prevTime = new Date(prev.dt_txt).getTime();
const currTime = new Date(curr.dt_txt).getTime();
const nowTime = now.getTime();
const prevDiff = Math.abs(prevTime - nowTime);
const currDiff = Math.abs(currTime - nowTime);
return prevDiff < currDiff ? prev : curr;
});
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
weather.value.description = closest.weather[0].description;
weather.value.tempMin = Math.round(closest.main.temp_min);
weather.value.tempMax = Math.round(closest.main.temp_max);
} catch (e) {
console.error('날씨 정보 가져오기 실패:', e);
}
});
});
const handleLogout = async () => {
await authStore.logout();
router.push('/login');
};
const goToMyPage = () => {
router.push('/mypage');
};
</script> </script>
<style scoped> <style scoped>
.weather-icon { .weather-icon {
width: 40%; width: 40%;
height: 40%; height: 40%;
}
.weather-desc {
font-size: 14px;
font-weight: 500;
line-height: 1.6;
}
.weather-temp {
font-size: 13px;
color: #888;
line-height: 1.2;
}
.weather-box {
display: flex;
align-items: center;
flex-shrink: 0;
max-width: 3000px;
white-space: nowrap;
overflow: hidden;
}
.custom-sunny-icon {
width: 5%;
height: auto;
}
@media (max-width: 1200px) {
.custom-sunny-icon {
width: 6%;
} }
} .weather-desc {
@media (max-width: 1100px) { font-size: 14px;
.custom-sunny-icon { font-weight: 500;
width: 14%; line-height: 1.6;
}
.weather-temp {
font-size: 13px;
color: #888;
line-height: 1.2;
}
.weather-box {
display: flex;
align-items: center;
flex-shrink: 0;
max-width: 3000px;
white-space: nowrap;
overflow: hidden;
}
.custom-sunny-icon {
width: 5%;
height: auto;
}
@media (max-width: 1200px) {
.custom-sunny-icon {
width: 6%;
}
}
@media (max-width: 1100px) {
.custom-sunny-icon {
width: 14%;
}
} }
}
</style> </style>

View File

@ -0,0 +1,71 @@
/*
작성자 : 서지희
작성일 : 2025-04-04
수정자 :
수정일 :
설명 :
*/
import { ref } from 'vue';
import { defineStore } from 'pinia';
import $api from '@api';
export const useWeatherStore = defineStore('weather', () => {
const weather = ref({
icon: '',
description: '',
tempMin: null,
tempMax: null,
});
const dailyWeatherList = ref([]);
const getWeatherInfo = async () => {
navigator.geolocation.getCurrentPosition(async position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
try {
const res = await $api.get(`/weather`, {
params: { lat, lon },
withCredentials: true,
});
if (!res?.data?.data) return;
const resData = res.data.data;
const raw = resData.weatherInfo;
const data = JSON.parse(raw);
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
console.error('날씨 데이터 형식 오류 또는 없음:', data);
return;
}
dailyWeatherList.value = resData.dailyWeatherList;
const now = new Date();
const closest = data.list.reduce((prev, curr) => {
const prevTime = new Date(prev.dt_txt).getTime();
const currTime = new Date(curr.dt_txt).getTime();
const nowTime = now.getTime();
const prevDiff = Math.abs(prevTime - nowTime);
const currDiff = Math.abs(currTime - nowTime);
return prevDiff < currDiff ? prev : curr;
});
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
weather.value.description = closest.weather[0].description;
weather.value.tempMin = Math.round(closest.main.temp_min);
weather.value.tempMax = Math.round(closest.main.temp_max);
} catch (e) {
console.error('날씨 정보 가져오기 실패:', e);
}
});
};
return {
weather,
dailyWeatherList,
getWeatherInfo,
};
});