
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
2024-11-19
<template>
<div style="height: 100%">
<div class="myplan mypage flex" style="height: 100%; padding: 50px">
<div
class="textbook book-purple"
style="background-color: white; width: 50%; height: 100%; text-align: center"
>
<div class="text">
<p class="title1" style="color: #fff">스케줄</p>
</div>
<div class="purple-scroll" style="overflow: auto; height: 85%; margin: 5px">
<div style="padding: 10px 20px">
<p
style="text-align: right; cursor: pointer; text-decoration: underline; padding-bottom: 5px"
class="title2"
@click="goToPage2('MyPlan2')"
>
학습 일정 변경하기
</p>
<p class="title1" v-if="!schedules || schedules.length === 0">오늘 학습할 내용이 없습니다.</p>
<div
class="flex-column"
style="gap: 20px"
v-else
v-for="(schedule, index) in schedules"
:key="index"
>
<div class="flex justify-between align-center" style="gap: 70px">
<div
class="wrap cs-pt planBox"
:class="{ 'cs-pt-clicked': isClicked }"
style="width: 100%; background-color: #f1eaff"
@click="goToPage('Dashboard', schedule.schdl_id)"
>
<div class="text-lf flex justify-between align-center" style="width: 100%">
<p class="title2" s>grade 3</p>
<button
type="button"
class="popup-close-btn"
@click="deleteSchedule(schedule.schdl_id)"
style="flex-basis: 25px"
>
<svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
</button>
</div>
<div class="text-lf flex justify-between align-center">
<div style="flex-basis: 40rem">
<div class="flex align-center mb10" style="gap: 10px">
<p class="title2">
<em
class="gray-bd"
style="background-color: #9528b7; color: white; font-size: 18px"
>{{ schedule.schdl_unit }}교시</em
>
</p>
<p class="title1">{{ schedule.schedule_time }}</p>
</div>
<div class="title-box mb10" style="display: flex">
<span class="title" style="font-size: 28px">{{
schedule.unit_nm
}}</span>
<p class="title2" style="margin: auto 0; margin-left: 1em">
{{ schedule.book_nm }}
</p>
</div>
</div>
<!-- <button v-if="schedule.finish == 'T'" type="button" title="바로가기" class="yellow-btn"
@click="goToPage('Dashboard', schedule.schdl_id)">학습완료</button>
<button v-else type="button" title="바로가기" class="yellow-btn"
@click="goToPage('Dashboard', schedule.schdl_id)"
style="flex-basis: 18rem">바로가기</button> -->
<div style="flex-basis: 100px">
<img
src="../../../resources/img/img214_19s.png"
alt=""
style="height: 100px; width: 100px"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="yellow-box mt30">
<div class="title-box flex justify-between align-center">
<div>
<p class="title">오늘 공부를 계획해봅시다.</p>
<p class="title1 mt20">스스로 학습 일정을 바꿔볼까요?</p>
</div>
<button type="button" title="바로가기" class="yellow-btn"
@click="goToPage2('MyPlan2')">바로가기</button>
</div>
</div> -->
<div style="width: 50%; margin-left: 3em">
<div class="flex">
<div style="display: flex">
<img src="../../../resources/img/new_img/plan/course_text.png" style="margin: auto 0" />
</div>
<div
style="justify-content: right; width: 100%; display: flex"
v-for="(ai_learning, index) in aiLearningList"
:key="index"
>
<div
style="margin-right: 2em"
@click="
goToPage2('AIDashboard', aiLearningList[index].unit_id);
recommendLearning();
"
>
<img src="../../../resources/img/new_img/plan/ai_course_1.png" />
</div>
<div style="margin-right: 2em" @click="goToPage2('AIDashboard', aiLearningList[index].unit_id)">
<img src="../../../resources/img/new_img/plan/ai_course_2.png" />
</div>
<div @click="goToPage2('AIDashboard', aiLearningList[index].unit_id)">
<img src="../../../resources/img/new_img/plan/ai_course_3.png" />
</div>
</div>
</div>
<div class="flex" style="margin-top: 3em">
<div style="display: flex">
<img src="../../../resources/img/new_img/plan/menu_text.png" style="margin: auto 0" />
</div>
<div class="mpcontainer">
<div class="mpbox" @click="goToPage2('PreviewNote')" style="margin-right: 2em; cursor: pointer">
<img src="../../../resources/img/new_img/icon/correct_icon.png" />
<p>채점결과</p>
</div>
<div class="mpbox" @click="goToPage2('MyPage')" style="margin-right: 2em; cursor: pointer">
<img src="../../../resources/img/new_img/icon/mypage_icon.png" />
<p>생활기록부</p>
</div>
<div class="mpbox" @click="goPopupOpen" style="margin-right: 2em; cursor: pointer">
<img src="../../../resources/img/new_img/icon/qNa_icon.png" />
<p>내문제질문</p>
</div>
<div class="mpbox" @click="goToPage2('PhotoBook')" style="cursor: pointer">
<img src="../../../resources/img/new_img/icon/photobook_icon.png" />
<p>포토북</p>
</div>
</div>
</div>
<!-- <div class="wrap mt30">
<p class="title1 mb20">AI 맞춤형 학습 코스는 어떨까요?</p>
<div class="imgGroup flex justify-between">
<div class="text-lf aiClick" v-for="(ai_learning, index) in aiLearningList" :key="index"
@click="goToPage2('AIDashboard', aiLearningList[index].unit_id)">
<img src="../../../resources/img/img215_22s.png" alt="" />
<p class="title2 mt10">추천 학습 단원</p>
</div>
</div>
</div> -->
<div class="mypage" style="display: flex; height: 50%; gap: 10px; margin-top: 4em">
<div
class="textbook book-green"
style="background-color: white; width: 50%; height: 100%; text-align: center"
>
<div class="text">
<p class="title1" style="color: #fff">오늘의 뉴스</p>
</div>
<div class="green-scroll" style="overflow: auto; height: 73%; margin: 5px">
<div style="padding: 10px">
<div v-for="(student, index) in news" :key="index">
<div class="flex align-center">
<div>
<img src="../../../resources/img/img16_s.png" alt="" />
</div>
<p class="news_font">
<span>{{ student.user_nm }}</span
>님이<br />
<span> {{ student.unit_nm }}</span
>을 다 끝냈습니다.
</p>
</div>
<hr style="margin: 10px 0" />
</div>
</div>
</div>
</div>
<div
class="textbook book-blue"
style="background-color: white; width: 50%; height: 100%; text-align: center"
>
<div class="text">
<p class="title1" style="color: #fff">학습 현황</p>
</div>
<div style="overflow: hidden; height: 75%">
<div class="flex justify-center">
<Dounutchart />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 질문하기 팝업 -->
<div class="popup-wrap" v-if="this.popupOpen === true" style="z-index: 100">
<div class="question-popup">
<div class="flex justify-between align-center">
<p class="question-text mt20">선생님께 질문하기</p>
<img
class="look-btn"
@click="goPopupClose"
src="../../../resources/img/btn25_93t_normal.png"
alt=""
/>
</div>
<p style="color: #8c8c8c; font-size: 20px; margin: 40px 0px">선생님! 질문있어요!!</p>
<div class="memo mt25">
<p class="title1 memo-text">내용</p>
<textarea name="" id="" placeholder="궁금한 것을 적어보세요." v-model="question"></textarea>
</div>
<div class="questionBtn-box flex justify-end" style="gap: 15px">
<button style="border-color: #eaedf4; color: #8c8c8c" @click="goPopupClose">취소하기</button>
<button
@click="updateQuestion"
style="border-color: #6327b9; color: white; background-color: #6327b9"
>
질문하기
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import SvgIcon from '@jamescoyle/vue-icon';
import { mdiMagnify, mdiWindowClose } from '@mdi/js';
import { mapActions } from 'vuex';
import { mapGetters } from 'vuex';
import Dounutchart from './chDounutchart.vue';
export default {
data() {
return {
mdiMagnify: mdiMagnify,
mdiWindowClose: mdiWindowClose,
showModal: false,
searchOpen: false,
schedules: [],
stdId: '2',
timeList: [
{ label: '1교시', time: '08:00 ~ 09:00', value: '1' },
{ label: '2교시', time: '09:00 ~ 10:00', value: '2' },
{ label: '3교시', time: '10:00 ~ 11:00', value: '3' },
{ label: '4교시', time: '11:00 ~ 12:00', value: '4' },
{ label: '5교시', time: '13:00 ~ 14:00', value: '5' },
{ label: '6교시', time: '14:00 ~ 15:00', value: '6' },
],
aiLearningList: [],
news: [],
popupOpen: false,
question: null,
};
},
methods: {
...mapActions(['updateSchdlId', 'updateBookId', 'updateUnitId']),
// 오늘의 뉴스
fetchNews() {
// const userId = this.getUserInfo.userId;
// console.log('오늘의 뉴스 아이디 : ', userId);
axios({
url: '/photo/selectPhotoInfo.json',
method: 'post',
hedaers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
// userId: userId,
userId: '1',
},
}).then((res) => {
console.log('오늘의 뉴스 - response : ', res.data);
this.news = res.data;
});
},
goToPage(page, scheduleId) {
const startScheduleIndex = this.schedules.findIndex((schedule) => schedule.schdl_id === scheduleId);
if (startScheduleIndex === -1) {
console.error('해당 스케줄을 찾을 수 없습니다.');
return;
}
const updates = [];
const currentSchedule = this.schedules[startScheduleIndex];
if (currentSchedule.finish === null || currentSchedule.finish === 'T') {
updates.push(
axios.post(
'/schedule/scheduleUpdate.json',
{ scheduleId: currentSchedule.schdl_id, finish: 'F' },
{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
}
)
);
}
for (let i = startScheduleIndex + 1; i < this.schedules.length; i++) {
const nextSchedule = this.schedules[i];
if (nextSchedule.finish === 'T') {
updates.push(
axios.post(
'/schedule/scheduleUpdate.json',
{ scheduleId: nextSchedule.schdl_id, finish: 'F' },
{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
}
)
);
}
}
Promise.all(updates)
.then(() => {
const schedule = this.schedules[startScheduleIndex];
// 대시보드 위치 저장
this.$store.dispatch('updateCurrentDashboard', 'Learning');
// this.$router.push({
// name: page,
// query: {
// schdl_id: schedule.schdl_id,
// book_id: schedule.book_id,
// unit_id: schedule.unit_id
// }
// });
// 상태 업데이트가 완료된 후 라우팅
Promise.all([
this.updateSchdlId(schedule.schdl_id),
this.updateBookId(schedule.book_id),
this.updateUnitId(schedule.unit_id),
])
.then(() => {
console.log('Book ID:', this.getBookId);
console.log('Unit ID:', this.getUnitId);
this.$router.push({ name: page });
})
.catch((error) => {
console.error('상태 업데이트 중 오류 발생:', error);
});
})
.catch((error) => {
console.error('Error updating schedules:', error);
alert('학습 계획을 업데이트하는 중 오류가 발생했습니다.');
});
},
goToPage2(page, unit_id) {
this.$store.dispatch('updateCurrentDashboard', 'AI');
this.$router.push({
name: page,
query: {
unit_id: unit_id,
},
});
},
showConfirm(type) {
let message = '';
if (type === 'cancel') {
message = '삭제하시겠습니까?';
} else if (type === 'reset') {
message = '초기화하시겠습니까?';
} else if (type === 'save') {
message = '등록하시겠습니까?';
}
if (confirm(message)) {
this.goBack();
}
},
closeModal() {
this.showModal = false;
},
buttonSearch() {
this.searchOpen = true;
},
closeBtn() {
this.searchOpen = false;
},
fetchSchedules() {
axios
.post(
'/schedule/selectSchedule.json',
{ stdId: this.stdId },
{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
}
)
.then((response) => {
this.schedules = response.data.map((schedule) => {
const matchingTime = this.timeList.find((time) => time.value === schedule.schdl_unit);
return {
...schedule,
schedule_time: matchingTime ? matchingTime.time : '시간 정보 없음',
};
});
console.log(this.schedules);
})
.catch((error) => {
console.error('fetchUnits - error:', error);
alert('단원 목록을 불러오는 중 오류가 발생했습니다.');
});
},
deleteSchedule(scheduleId) {
axios
.post(
'/schedule/scheduleDelete.json',
{ scheduleId: scheduleId },
{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
}
)
.then((response) => {
alert('학습일정이 삭제되었습니다.');
window.location.reload();
})
.catch((error) => {
console.error('fetchUnits - error:', error);
alert('단원 목록을 불러오는 중 오류가 발생했습니다.');
});
},
selectAiLearning: function () {
const vm = this;
axios({
url: '/aiLearning/selectAILearning.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
user_id: 'USID_000000000000002',
},
})
.then(function (response) {
console.log('aiLearningList - response : ', response.data);
vm.aiLearningList = response.data;
})
.catch(function (error) {
console.log('aiLearningList - error : ', error);
alert('ai learning 조회에 오류가 발생했습니다.');
});
},
recommendLearning() {
axios({
url: 'http://165.229.169.32:35716/recommend_and_insert',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
top_n: 11,
user_id: 'USID_000000000000002',
},
})
.then((response) => {
console.log('recommendLearning list - response : ', response.data);
})
.catch((err) => {
console.log('추천 에러: ', err);
});
},
// 질문 업데이트 메서드
updateQuestion() {
if (this.question === null) {
alert('질문을 입력해주세요');
return;
}
axios
.post('/studentInfo/updateQuestion.json', {
userId: this.userId,
// userId: 'USID_000000000000002',
studentQuestion: this.question,
})
.then((response) => {
console.log('질문이 성공적으로 업데이트되었습니다.');
alert('질문이 성공적으로 업데이트되었습니다.');
})
.catch((error) => {
console.error('질문 업데이트 실패:', error);
alert('질문 업데이트에 실패했습니다.');
});
this.question = null;
},
goPopupOpen() {
this.popupOpen = true;
},
goPopupClose() {
this.popupOpen = false;
this.question = null;
},
},
watch: {},
computed: {
...mapGetters(['getBookId', 'getUnitId', 'getUserInfo']),
},
components: {
SvgIcon,
Dounutchart: Dounutchart,
},
mounted() {
console.log('Main2 mounted');
this.fetchSchedules();
this.selectAiLearning();
this.fetchNews();
},
};
</script>
<style>
.planBox {
/* box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 20px, rgba(0, 0, 0, 0.096) 0px 6px 6px; */
border: none;
margin: 0px 0px 20px;
}
.aiClick {
cursor: pointer;
}
.mypgBack {
background-image: url('../../../resources/img/new_img/plan/background.png');
}
.mpcontainer {
display: flex;
justify-content: right;
width: 100%;
}
.mpbox {
background-color: white;
border-radius: 20px;
text-align: center;
aspect-ratio: 1 / 1;
width: 100px;
display: grid;
align-items: center;
}
.mpbox img {
width: 4.5em;
margin: 10px auto 0 auto;
}
.mpbox p {
margin-top: 0.5em;
font-size: 16px;
font-family: 'ONEMobilePOPOTF';
}
.question-popup {
background-color: white;
border-radius: 10px;
padding: 30px 40px;
position: absolute;
top: 15%;
left: 25%;
width: 100rem;
}
.question-text {
font-family: 'ONEMobilePOPOTF';
font-size: 32px;
color: #6327b9;
}
.memo-text {
font-family: 'ONEMobilePOPOTF';
color: #6327b9;
}
.memo textarea {
border: 2px solid #cac0e3;
border-radius: 10px;
width: 100%;
padding: 20px;
height: 30rem;
margin: 20px 0px 40px;
}
.questionBtn-box button {
font-size: 18px;
padding: 8px 30px;
border: 2px solid;
border-radius: 8px;
font-weight: bold;
font-family: 'ONEMobileOTF-Regular';
}
.news_font {
margin: 10px;
text-align: justify;
font-size: 18px;
}
.news_font span {
font-size: 18px;
color: #64a56d;
}
</style>