Compare commits
No commits in common. "a11aa8fbd0f25c4cfa88f91f37170e46d912d724" and "97236619f076c3cf15add12c2a2debf7e553de3c" have entirely different histories.
a11aa8fbd0
...
97236619f0
@ -56,8 +56,6 @@ dependencies {
|
|||||||
implementation ("org.seleniumhq.selenium:selenium-java:4.10.0")
|
implementation ("org.seleniumhq.selenium:selenium-java:4.10.0")
|
||||||
|
|
||||||
implementation ("org.commonmark:commonmark:0.18.0")
|
implementation ("org.commonmark:commonmark:0.18.0")
|
||||||
implementation ("net.coobird:thumbnailator:0.4.14")
|
|
||||||
|
|
||||||
|
|
||||||
implementation ("com.drewnoakes:metadata-extractor:2.19.0")
|
implementation ("com.drewnoakes:metadata-extractor:2.19.0")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
package kr.lunaticbum.back.lun.configs
|
package kr.lunaticbum.back.lun.configs
|
||||||
|
|
||||||
|
import io.qdrant.client.QdrantClient
|
||||||
|
import org.springframework.ai.ollama.api.OllamaApi
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.http.CacheControl
|
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||||
import java.time.Duration
|
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -17,15 +17,12 @@ class AppConfig : WebMvcConfigurer {
|
|||||||
@Value("\${resource.location}")
|
@Value("\${resource.location}")
|
||||||
private val resourceLocation: String? = null
|
private val resourceLocation: String? = null
|
||||||
|
|
||||||
val cacheControl: CacheControl = CacheControl.maxAge(Duration.ofDays(365))
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun authInterceptor(): BumsInterceptor {
|
fun authInterceptor(): BumsInterceptor {
|
||||||
return BumsInterceptor()
|
return BumsInterceptor()
|
||||||
}
|
}
|
||||||
override fun addResourceHandlers(registry: org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry) {
|
override fun addResourceHandlers(registry: org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry) {
|
||||||
|
registry.addResourceHandler(resourceHandler).addResourceLocations(resourceLocation)
|
||||||
registry.addResourceHandler(resourceHandler).addResourceLocations(resourceLocation).setCacheControl(cacheControl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||||
|
|||||||
@ -4,9 +4,6 @@ import com.google.gson.Gson
|
|||||||
import jakarta.servlet.http.Cookie
|
import jakarta.servlet.http.Cookie
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.ApiKeyWordKey
|
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
|
||||||
import kr.lunaticbum.back.lun.model.UserManager
|
import kr.lunaticbum.back.lun.model.UserManager
|
||||||
import kr.lunaticbum.back.lun.service.JwtService
|
import kr.lunaticbum.back.lun.service.JwtService
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
@ -101,8 +98,6 @@ class BumsInterceptor : HandlerInterceptor {
|
|||||||
(it.getAttribute(WRITE_PERMISSION_KEY) as? Boolean)?.let { permission ->
|
(it.getAttribute(WRITE_PERMISSION_KEY) as? Boolean)?.let { permission ->
|
||||||
if (permission) {
|
if (permission) {
|
||||||
modelAndView?.modelMap?.put(WRITE_PERMISSION_KEY,"OK")
|
modelAndView?.modelMap?.put(WRITE_PERMISSION_KEY,"OK")
|
||||||
modelAndView?.modelMap?.put(EncTypeKey, EncType11)
|
|
||||||
modelAndView?.modelMap?.put(ApiKeyWordKey,"Def")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import kr.lunaticbum.back.lun.model.*
|
|||||||
import kr.lunaticbum.back.lun.service.JwtService
|
import kr.lunaticbum.back.lun.service.JwtService
|
||||||
import kr.lunaticbum.back.lun.utils.LogService
|
import kr.lunaticbum.back.lun.utils.LogService
|
||||||
import kr.lunaticbum.back.lun.utils.getFileExtension
|
import kr.lunaticbum.back.lun.utils.getFileExtension
|
||||||
import net.coobird.thumbnailator.Thumbnails
|
|
||||||
import org.commonmark.node.Node
|
import org.commonmark.node.Node
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
import org.commonmark.renderer.html.HtmlRenderer
|
import org.commonmark.renderer.html.HtmlRenderer
|
||||||
@ -26,11 +25,13 @@ import org.springframework.beans.factory.annotation.Autowired
|
|||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.core.io.Resource
|
import org.springframework.core.io.Resource
|
||||||
import org.springframework.core.io.UrlResource
|
import org.springframework.core.io.UrlResource
|
||||||
|
import org.springframework.data.domain.Pageable
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import org.springframework.web.reactive.function.client.WebClient
|
import org.springframework.web.reactive.function.client.WebClient
|
||||||
|
import reactor.kotlin.core.publisher.toMono
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -218,54 +219,16 @@ class BlogController() {
|
|||||||
val firstImg: Element? = doc.select("img")?.first()
|
val firstImg: Element? = doc.select("img")?.first()
|
||||||
val imgSrc: String = firstImg?.attr("src") ?: ""
|
val imgSrc: String = firstImg?.attr("src") ?: ""
|
||||||
it.image = imgSrc
|
it.image = imgSrc
|
||||||
it.thumb = imgSrc.replaceBeforeLast(".", "_thumbnail.")
|
|
||||||
generateThumbnail(imgSrc.split("/").last(), 200)
|
|
||||||
it.html = doc.text()
|
it.html = doc.text()
|
||||||
}
|
}
|
||||||
it.title = if ((it.title?.length ?: 0) >= 1) it.title else ""
|
it.title = if ((it.title?.length ?: 0) >= 1) it.title else ""
|
||||||
}
|
}
|
||||||
})
|
}.chunked(2))
|
||||||
}catch (ex: Exception){ex.printStackTrace()}
|
}catch (ex: Exception){ex.printStackTrace()}
|
||||||
|
|
||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateThumbnail(originalPath: String, targetWidth: Int) {
|
|
||||||
try {
|
|
||||||
val originalFile = File("$uploadPath${File.separator}$originalPath")
|
|
||||||
|
|
||||||
// 썸네일 경로 생성 (예: /upload/uuid.jpg → /upload/uuid_thumbnail.jpg)
|
|
||||||
val thumbnailPath = originalFile.path
|
|
||||||
.replaceBeforeLast(".", "_thumbnail.")
|
|
||||||
|
|
||||||
|
|
||||||
val thumbnailFile = File(thumbnailPath)
|
|
||||||
// 썸네일 이미 존재하면 종료
|
|
||||||
if (thumbnailFile.exists()) {
|
|
||||||
println("썸네일 이미 존재: $thumbnailPath")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 원본 파일 존재 확인
|
|
||||||
if (!originalFile.exists()) {
|
|
||||||
println("원본 파일 없음: $originalPath")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 썸네일 생성 (가로 기준 비율 유지)
|
|
||||||
Thumbnails.of(originalFile)
|
|
||||||
.width(targetWidth)
|
|
||||||
.keepAspectRatio(true)
|
|
||||||
.toFile(thumbnailPath)
|
|
||||||
|
|
||||||
println("썸네일 생성 완료: $thumbnailPath")
|
|
||||||
} catch (e: IOException) {
|
|
||||||
println("썸네일 생성 실패: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("recent")
|
@GetMapping("recent")
|
||||||
fun recent() : ResultMV{
|
fun recent() : ResultMV{
|
||||||
val vm = ResultMV("content/blog/viewer")
|
val vm = ResultMV("content/blog/viewer")
|
||||||
@ -308,75 +271,80 @@ class BlogController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("post/imageUpload")
|
@PostMapping("post/imageUpload")
|
||||||
fun postImage(@RequestPart("file") upload: MultipartFile, res: HttpServletResponse, req: HttpServletRequest): ResponseEntity<FileSaveResult> {
|
fun postImage(@RequestPart("file") upload: MultipartFile, res: HttpServletResponse, req: HttpServletRequest) : ResponseEntity<FileSaveResult> {
|
||||||
var lResultCode = 0
|
var lResultCode = 0
|
||||||
var lResultMsg = "Success"
|
var lResultMsg = "Suscces"
|
||||||
var out: FileOutputStream? = null
|
var out: OutputStream? = null
|
||||||
var targetFile: File? = null
|
var printWriter: PrintWriter? = null
|
||||||
|
var targetFile : File? = null
|
||||||
val uuid = UUID.randomUUID()
|
logService.log("imgUploadPath ${upload.originalFilename}")
|
||||||
|
res.characterEncoding = "utf-8"
|
||||||
|
res.contentType = "text/html;charset=utf-8"
|
||||||
|
var uuid = UUID.randomUUID()
|
||||||
val extension: String = getFileExtension(upload.originalFilename) ?: ""
|
val extension: String = getFileExtension(upload.originalFilename) ?: ""
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
logService.log("imgUploadPath ${uuid.toString()}")
|
||||||
|
|
||||||
val bytes = upload.bytes
|
val bytes = upload.bytes
|
||||||
|
|
||||||
val f = File(uploadPath)
|
var f = File(uploadPath)
|
||||||
if (!f.exists()) f.mkdirs()
|
// logService.log("imgUploadPath ${f.parentFile.parentFile.parentFile.parentFile.absoluteFile}")
|
||||||
|
// logService.log("imgUploadPath ${f.parentFile.parentFile.parentFile.absoluteFile}")
|
||||||
|
// logService.log("imgUploadPath ${f.parentFile.parentFile.absoluteFile}")
|
||||||
|
// logService.log("imgUploadPath ${f.parentFile.absoluteFile}")
|
||||||
|
logService.log("imgUploadPath ${f.exists()}")
|
||||||
|
logService.log("imgUploadPath ${f.absolutePath}")
|
||||||
|
if (f.exists() == false) f.mkdirs()
|
||||||
|
// 실제 이미지 저장 경로
|
||||||
|
val imgUploadPath = (uploadPath + File.separator + uuid).toString() + "." + extension
|
||||||
|
logService.log("imgUploadPath $imgUploadPath")
|
||||||
|
targetFile = File(imgUploadPath)
|
||||||
|
if(targetFile.parentFile.exists() == false)targetFile.parentFile.mkdirs()
|
||||||
|
|
||||||
// 원본 이미지 저장 경로
|
// 이미지 저장
|
||||||
val originalImagePath = "$uploadPath${File.separator}$uuid.$extension"
|
out = FileOutputStream(imgUploadPath)
|
||||||
logService.log("Original image path: $originalImagePath")
|
|
||||||
|
|
||||||
// 썸네일 저장 경로
|
|
||||||
val thumbnailPath = "$uploadPath${File.separator}${uuid}_thumbnail.$extension"
|
|
||||||
logService.log("Thumbnail path: $thumbnailPath")
|
|
||||||
|
|
||||||
targetFile = File(originalImagePath)
|
|
||||||
if (!targetFile.parentFile.exists()) targetFile.parentFile.mkdirs()
|
|
||||||
|
|
||||||
// 원본 이미지 저장
|
|
||||||
out = FileOutputStream(originalImagePath)
|
|
||||||
out.write(bytes)
|
out.write(bytes)
|
||||||
out.flush()
|
out.flush()
|
||||||
|
|
||||||
// 썸네일 생성 및 저장
|
// ckEditor 로 전송
|
||||||
Thumbnails.of(originalImagePath)
|
// printWriter = res.writer
|
||||||
.width(200) // 가로 크기를 설정
|
// val callback = req.getParameter("CKEditorFuncNum")
|
||||||
.keepAspectRatio(true)
|
// val fileUrl = "/blog/post/image/$uuid.$extension"
|
||||||
.toFile(thumbnailPath)
|
|
||||||
|
|
||||||
logService.log("Original image saved: ${File(originalImagePath).exists()}")
|
// printWriter.println(
|
||||||
logService.log("Thumbnail saved: ${File(thumbnailPath).exists()}")
|
// ("<script type='text/javascript'>"
|
||||||
|
// + "window.parent.CKEDITOR.tools.callFunction("
|
||||||
// 메타데이터 읽기 (원본 이미지에서)
|
// + callback + ",'" + fileUrl + "','이미지를 업로드하였습니다.')"
|
||||||
val metadata: Metadata? = ImageMetadataReader.readMetadata(File(originalImagePath))
|
// + "</script>")
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// printWriter.flush()
|
||||||
|
logService.log("imgUploadPath $imgUploadPath")
|
||||||
|
logService.log("imgUploadPath ${File(imgUploadPath).exists()}")
|
||||||
|
val metadata: Metadata? = ImageMetadataReader.readMetadata(File(imgUploadPath))
|
||||||
metadata?.let {
|
metadata?.let {
|
||||||
it.directories?.forEach { directory ->
|
it.directories?.forEach { directory ->
|
||||||
logService.log(directory.name)
|
logService.log(directory.name)
|
||||||
logService.log(directory.tags.map { tag ->
|
logService.log(directory.tags.map { tag -> logService.log("tag.tagName >>> ${tag.tagName} || tag.description ${tag.description}")}.joinToString(" \n"))
|
||||||
logService.log("tag.tagName >>> ${tag.tagName} || tag.description ${tag.description}")
|
|
||||||
}.joinToString(" \n"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
lResultCode = 1
|
|
||||||
lResultMsg = "Error: ${e.message}"
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
out?.close()
|
out?.close()
|
||||||
|
printWriter?.close()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val responce = ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(FileSaveResult().apply {
|
||||||
|
|
||||||
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(FileSaveResult().apply {
|
|
||||||
this.resultCode = lResultCode
|
this.resultCode = lResultCode
|
||||||
this.resultMsg = lResultMsg
|
this.resultMsg = lResultMsg
|
||||||
this.fileName = "$uuid.$extension"
|
this.fileName = "$uuid.$extension"
|
||||||
this.thumbnailName = "${uuid}_thumbnail.$extension"
|
|
||||||
})
|
})
|
||||||
|
return responce
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -36,7 +36,6 @@ class Post {
|
|||||||
|
|
||||||
var html : String? = null
|
var html : String? = null
|
||||||
var image : String? = null
|
var image : String? = null
|
||||||
var thumb : String? = null
|
|
||||||
|
|
||||||
var writer : String? = null
|
var writer : String? = null
|
||||||
var writeTime : Long = 0
|
var writeTime : Long = 0
|
||||||
|
|||||||
@ -18,5 +18,4 @@ open class LoginResult : ResponceResult() {
|
|||||||
@Getter
|
@Getter
|
||||||
class FileSaveResult : ResponceResult() {
|
class FileSaveResult : ResponceResult() {
|
||||||
var fileName : String? = null
|
var fileName : String? = null
|
||||||
var thumbnailName : String? = null
|
|
||||||
}
|
}
|
||||||
@ -3384,59 +3384,4 @@ button.small,
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Login Popup*/
|
|
||||||
.login_overlay {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login_popup {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background-color: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 5px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.login_form {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login_form h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login_form input {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*.login_form button {*/
|
|
||||||
/* width: 100%;*/
|
|
||||||
/* padding: 10px;*/
|
|
||||||
/* background-color: #4CAF50;*/
|
|
||||||
/* color: white;*/
|
|
||||||
/* border: none;*/
|
|
||||||
/* cursor: pointer;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
.login_close {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
font-size: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
@ -48,9 +48,9 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #00000044;
|
background: #00000044;
|
||||||
}
|
}
|
||||||
/*#title_field {*/
|
#title_field {
|
||||||
/*font-size: 20px;*/
|
font-size: 20px;
|
||||||
/*}*/
|
}
|
||||||
|
|
||||||
.pop_layer .pop_container {
|
.pop_layer .pop_container {
|
||||||
padding: 20px 25px;
|
padding: 20px 25px;
|
||||||
|
|||||||
@ -167,4 +167,4 @@ footer {
|
|||||||
height: 5vh;
|
height: 5vh;
|
||||||
min-height: 5vh;
|
min-height: 5vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@ -16,8 +16,8 @@ let baseData = {
|
|||||||
'writeTime' : 0,
|
'writeTime' : 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToEditor(id) {
|
function goToEditor(path,id,sk) {
|
||||||
location.href = getMainPath() + '/blog/editor/' + id;
|
location.href = path + id+"?token="+sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,4 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
const loginForm = document.getElementById('loginFormElement');
|
|
||||||
loginForm.addEventListener('submit', function(e) {
|
|
||||||
e.preventDefault(); // 기본 폼 제출 동작 방지
|
|
||||||
submitLoginForm();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
onload = function() {
|
onload = function() {
|
||||||
history.replaceState({}, null, location.pathname);
|
history.replaceState({}, null, location.pathname);
|
||||||
// var accToken = get_cookie("access")
|
// var accToken = get_cookie("access")
|
||||||
@ -14,31 +8,6 @@ onload = function() {
|
|||||||
document.cookie = "access=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
document.cookie = "access=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||||
document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||||
document.cookie = "CLEAR=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
document.cookie = "CLEAR=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||||
|
|
||||||
var currentList = [{"page":["posts"],"id":"menu_posts"},{"page":["licenses"],"id":"menu_drop"},{"page":["licenses"],"id":"menu_drop"}]
|
|
||||||
if(location.pathname.length > 1) {
|
|
||||||
// 1. 모든 'current' 클래스를 가진 요소를 선택하고 제거
|
|
||||||
// const currentElements = document.querySelectorAll('.current');
|
|
||||||
// currentElements.forEach(element => {
|
|
||||||
// element.classList.remove('current');
|
|
||||||
// });
|
|
||||||
currentList.forEach(element => {
|
|
||||||
element.page.forEach((page, index) => {
|
|
||||||
console.log(location.pathname);
|
|
||||||
if (location.pathname.includes(page)) {
|
|
||||||
const targetElement = document.getElementById(element.id);
|
|
||||||
if (targetElement) {
|
|
||||||
targetElement.classList.add('current');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const targetElement = document.getElementById('menu_home');
|
|
||||||
if (targetElement) {
|
|
||||||
targetElement.classList.add('current');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// onbeforeunload = function () {
|
// onbeforeunload = function () {
|
||||||
// var accToken = get_cookie("access")
|
// var accToken = get_cookie("access")
|
||||||
@ -291,75 +260,4 @@ function layer_popup(el){
|
|||||||
|
|
||||||
function urldecode(t){
|
function urldecode(t){
|
||||||
return decodeURI(t)
|
return decodeURI(t)
|
||||||
}
|
|
||||||
|
|
||||||
function openLoginPopup(formType) {
|
|
||||||
|
|
||||||
document.getElementById('overlay').style.display = 'block';
|
|
||||||
document.getElementById('loginForm').style.display = formType === 'login' ? 'block' : 'none';
|
|
||||||
document.getElementById('signupForm').style.display = formType === 'signup' ? 'block' : 'none';
|
|
||||||
|
|
||||||
if(formType === 'login') {
|
|
||||||
const loginIdInput = document.getElementById('loginId');
|
|
||||||
loginIdInput.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePopup() {
|
|
||||||
document.getElementById('overlay').style.display = 'none';
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// function submitForm(formType) {
|
|
||||||
// alert(formType === 'login' ? '로그인 시도' : '회원가입 시도');
|
|
||||||
// closePopup();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
function submitLoginForm() {
|
|
||||||
// const id = document.getElementById('loginId').value;
|
|
||||||
// const password = document.getElementById('loginPassword').value;
|
|
||||||
let user_id = document.getElementById('loginId')
|
|
||||||
let user_pw = document.getElementById('loginPassword')
|
|
||||||
let data = {
|
|
||||||
'user_id': user_id.value,
|
|
||||||
'user_pw': user_pw.value,
|
|
||||||
}
|
|
||||||
postLogin(getMainPath()+"/user/login.ajax",user_pw.data,JSON.stringify(data),user_pw.data, function (data) {
|
|
||||||
closePopup()
|
|
||||||
if (data.isOk) {
|
|
||||||
document.cookie = "access=" + data.token.split(";")[0]+";"
|
|
||||||
window.sessionStorage.setItem("REFRESH",data.refresh.split(";")[0])
|
|
||||||
document.location.replace(location.href)
|
|
||||||
} else {
|
|
||||||
if (data.resultCode === 7100) {
|
|
||||||
if(confirm(`너 누구임 정보 없는데?!\n${data.resultMsg}[${data.resultCode}]\n가입 할래!?`)){
|
|
||||||
document.location.replace(getMainPath() + "/user/join")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert(`너 누구임?!\n${data.resultMsg}[${data.resultCode}]`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// AJAX 요청
|
|
||||||
// fetch('/login', {
|
|
||||||
// method: 'POST',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json',
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify({ id, password }),
|
|
||||||
// })
|
|
||||||
// .then(response => response.json())
|
|
||||||
// .then(data => {
|
|
||||||
// if (data.success) {
|
|
||||||
// alert('로그인 성공!');
|
|
||||||
// // 로그인 성공 후 처리 (예: 페이지 리다이렉트)
|
|
||||||
// } else {
|
|
||||||
// alert('로그인 실패: ' + data.message);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .catch(error => {
|
|
||||||
// console.error('Error:', error);
|
|
||||||
// alert('로그인 중 오류가 발생했습니다.');
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
@ -23,19 +23,30 @@
|
|||||||
baseData.firstPostLon = [[${srcPost.firstPostLon}]];
|
baseData.firstPostLon = [[${srcPost.firstPostLon}]];
|
||||||
baseData.writeTime = [[${srcPost.writeTime}]];
|
baseData.writeTime = [[${srcPost.writeTime}]];
|
||||||
getLocation()
|
getLocation()
|
||||||
// var style = getComputedStyle(document.body)
|
var style = getComputedStyle(document.body)
|
||||||
// console.log(style.getPropertyValue('--ContentVerticalMargin'))
|
console.log(style.getPropertyValue('--ContentVerticalMargin'))
|
||||||
// console.log(window.c)
|
console.log(window.c)
|
||||||
// console.log(style.getPropertyValue('--FooterHeight'))
|
console.log(style.getPropertyValue('--FooterHeight'))
|
||||||
// console.log(style.getPropertyValue('--TopHeight'))
|
console.log(style.getPropertyValue('--TopHeight'))
|
||||||
|
document.querySelector("#title_field").value = baseData.title
|
||||||
|
var editorHeght = (
|
||||||
|
document.querySelector('#main_layer').getBoundingClientRect().height -
|
||||||
|
(
|
||||||
|
Number(style.getPropertyValue('--ButtonHegit').replace("px","") * 3)
|
||||||
|
+ Number(style.getPropertyValue('--TopHeight').replace("px",""))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
editor = new toastui.Editor({
|
editor = new toastui.Editor({
|
||||||
el: document.querySelector('#editor'),
|
el: document.querySelector('#editor'),
|
||||||
previewStyle: 'tab',
|
previewStyle: 'tab',
|
||||||
height: '900px',
|
height: editorHeght + 'px',
|
||||||
width:'95%',
|
width:'95%',
|
||||||
|
theme:'dark',
|
||||||
usageStatistics : false,
|
usageStatistics : false,
|
||||||
toolbar:null,
|
toolbar:null,
|
||||||
initialValue:baseData.content,
|
initialValue:baseData.content,
|
||||||
|
theme:"dark",
|
||||||
initialEditType:"wysiwyg",
|
initialEditType:"wysiwyg",
|
||||||
hooks: {
|
hooks: {
|
||||||
addImageBlobHook: (blob, callback) => {
|
addImageBlobHook: (blob, callback) => {
|
||||||
@ -73,32 +84,24 @@
|
|||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
|
<div id="main_layer">
|
||||||
<section class="wrapper style2" >
|
|
||||||
<th:block th:if="${PERMISSION == 'OK'}">
|
|
||||||
<div class="container" >
|
|
||||||
<header class="major">
|
|
||||||
<h3><label for="title_field"><input id="title_field" th:value="${srcPost.title}"></label></h3>
|
|
||||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
</th:block>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="wrapper style2">
|
|
||||||
<th:block th:if="${PERMISSION != 'OK'}">
|
<th:block th:if="${PERMISSION != 'OK'}">
|
||||||
<h1>권한이 없는 뎁쇼?!</h1>
|
<h1>권한이 없는 뎁쇼?!</h1>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:if="${PERMISSION == 'OK'}">
|
<th:block th:if="${PERMISSION == 'OK'}">
|
||||||
|
|
||||||
|
<label for="title_field"></label><input id="title_field" class="write_option">
|
||||||
|
|
||||||
<div id="editor" ></div>
|
<div id="editor" ></div>
|
||||||
<div class="write_controllbox">
|
<div class="write_controllbox">
|
||||||
|
|
||||||
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
|
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
|
||||||
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
|
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
|
||||||
<label for="location_field"></label><input class="write_option" readonly id="location_field"/>
|
<label for="location_field"></label><input class="write_option" readonly id="location_field"/>
|
||||||
</div>
|
</div>
|
||||||
<h1><button id="save" class="write_option" style="width: 100%; position: relative" onclick="save()">저장하셈</button></h1>
|
<h1><button id="save" class="write_option" style="width: 100%; position: relative" onclick="save()">저장하셈</button></h1>
|
||||||
</th:block>
|
</th:block>
|
||||||
</section>
|
</div>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="popup_layer">
|
<th:block layout:fragment="popup_layer">
|
||||||
<div id="popLayer1" class="pop_layer">
|
<div id="popLayer1" class="pop_layer">
|
||||||
|
|||||||
@ -14,6 +14,17 @@
|
|||||||
let onChange = () => {console.log(editor.getMarkdown())}
|
let onChange = () => {console.log(editor.getMarkdown())}
|
||||||
document.addEventListener("DOMContentLoaded", onLoaded);
|
document.addEventListener("DOMContentLoaded", onLoaded);
|
||||||
function onLoaded() {
|
function onLoaded() {
|
||||||
|
// 1. 모든 'current' 클래스를 가진 요소를 선택하고 제거
|
||||||
|
const currentElements = document.querySelectorAll('.current');
|
||||||
|
currentElements.forEach(element => {
|
||||||
|
element.classList.remove('current');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 특정 조건에 맞는 요소에 'current' 클래스 추가 (예: ID가 'targetElement'인 요소)
|
||||||
|
const targetElement = document.getElementById('menu_posts');
|
||||||
|
if (targetElement) {
|
||||||
|
targetElement.classList.add('current');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -54,16 +65,30 @@
|
|||||||
<div class="col-6 col-12-narrower imp-narrower">
|
<div class="col-6 col-12-narrower imp-narrower">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<article>
|
<article>
|
||||||
<section class="col-6 col-12-narrower imp-narrower" th:each="post : ${Posts}">
|
<header>
|
||||||
<!-- <span th:text="${cell}"></span>-->
|
<h2>Two Sidebar</h2>
|
||||||
<div class="box post" onclick="goToViewer(this)" th:data="${post.id}">
|
<p>Yup. Two sidebars at the same time.</p>
|
||||||
<a href="#" class="image left"><img th:src="${#strings.length(post.thumb) > 0} ? ${post.thumb} : 'images/pic01.jpg'" alt="" /></a>
|
</header>
|
||||||
<div class="inner">
|
|
||||||
<h3 th:text="${#strings.length(post.title) > 0} ? ${post.title} : ('untitled[' + ${#temporals.format(T(java.time.Instant).ofEpochMilli(post.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')} + ']')"></h3>
|
<span class="image featured"><img src="images/banner.jpg" alt="" /></span>
|
||||||
<p th:text="${#strings.abbreviate(post.html, 80)}" class="ellipsis"></p>
|
|
||||||
</div>
|
<p>Phasellus quam turpis, feugiat sit amet ornare in, hendrerit in lectus.
|
||||||
</div>
|
Praesent semper mod quis eget mi. Etiam eu ante risus. Aliquam erat volutpat.
|
||||||
</section>
|
Aliquam luctus et mattis lectus sit amet pulvinar. Nam turpis nisi
|
||||||
|
consequat etiam lorem ipsum dolor sit amet nullam.</p>
|
||||||
|
|
||||||
|
<h3>And Yet Another Subheading</h3>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ac quam risus, at tempus
|
||||||
|
justo. Sed dictum rutrum massa eu volutpat. Quisque vitae hendrerit sem. Pellentesque lorem felis,
|
||||||
|
ultricies a bibendum id, bibendum sit amet nisl. Mauris et lorem quam. Maecenas rutrum imperdiet
|
||||||
|
rhoncus dui quis euismod. Maecenas lorem tellus, congue et condimentum ac, ullamcorper non sapien.
|
||||||
|
Donec sagittis massa et leo semper a scelerisque metus faucibus. Morbi congue mattis mi.
|
||||||
|
Phasellus sed nisl vitae risus tristique volutpat. Cras rutrum commodo luctus.</p>
|
||||||
|
|
||||||
|
<p>Phasellus odio risus, faucibus et viverra vitae, eleifend ac purus. Praesent mattis, enim
|
||||||
|
quis hendrerit porttitor, sapien tortor viverra magna, sit amet rhoncus nisl lacus nec arcu.
|
||||||
|
Maecenas tortor mauris, consectetur pellentesque dapibus eget, tincidunt vitae arcu.
|
||||||
|
Vestibulum purus augue, tincidunt sit amet iaculis id, porta eu purus.</p>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -30,22 +30,12 @@
|
|||||||
initialValue:baseData.content,
|
initialValue:baseData.content,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function loadEditor() {
|
|
||||||
goToEditor([[${srcPost.id}]]);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
<section class="wrapper style2">
|
<section class="wrapper style2">
|
||||||
|
<div class="container">
|
||||||
<div class="container" th:if="${PERMISSION == 'OK'}" onclick="loadEditor()">
|
<header class="major" >
|
||||||
<header class="major">
|
|
||||||
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
|
||||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
<div class="container" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
|
|
||||||
<header class="major">
|
|
||||||
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
||||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
<section class="col-6 col-12-narrower" th:each="post : ${row}">
|
<section class="col-6 col-12-narrower" th:each="post : ${row}">
|
||||||
<!-- <span th:text="${cell}"></span>-->
|
<!-- <span th:text="${cell}"></span>-->
|
||||||
<div class="box post" onclick="goToViewer(this)" th:data="${post.id}">
|
<div class="box post" onclick="goToViewer(this)" th:data="${post.id}">
|
||||||
<a href="#" class="image left"><img th:src="${#strings.length(post.thumb) > 0} ? ${post.thumb} : 'images/pic01.jpg'" alt="" /></a>
|
<a href="#" class="image left"><img th:src="${#strings.length(post.image) > 0} ? ${post.image} : 'images/pic01.jpg'" alt="" /></a>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3 th:text="${#strings.length(post.title) > 0} ? ${post.title} : ('untitled[' + ${#temporals.format(T(java.time.Instant).ofEpochMilli(post.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')} + ']')"></h3>
|
<h3 th:text="${#strings.length(post.title) > 0} ? ${post.title} : ('untitled[' + ${#temporals.format(T(java.time.Instant).ofEpochMilli(post.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')} + ']')"></h3>
|
||||||
<p th:text="${#strings.abbreviate(post.html, 80)}" class="ellipsis"></p>
|
<p th:text="${#strings.abbreviate(post.html, 80)}" class="ellipsis"></p>
|
||||||
@ -73,12 +73,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="col-4 col-12-narrower">
|
<section class="col-4 col-12-narrower">
|
||||||
<div class="box highlight" th:if="${PERMISSION == 'OK'}" onclick=gotoWrite()>
|
<div class="box highlight">
|
||||||
<i class="icon solid major fa-pencil-alt"></i>
|
|
||||||
<h3>글쓰기[Writing]</h3>
|
|
||||||
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
|
||||||
</div>
|
|
||||||
<div class="box highlight" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
|
|
||||||
<i class="icon solid major fa-pencil-alt"></i>
|
<i class="icon solid major fa-pencil-alt"></i>
|
||||||
<h3>글쓰기[Writing]</h3>
|
<h3>글쓰기[Writing]</h3>
|
||||||
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
||||||
|
|||||||
@ -14,8 +14,10 @@
|
|||||||
let onChange = () => {console.log(editor.getMarkdown())}
|
let onChange = () => {console.log(editor.getMarkdown())}
|
||||||
document.addEventListener("DOMContentLoaded", onLoaded);
|
document.addEventListener("DOMContentLoaded", onLoaded);
|
||||||
function onLoaded() {
|
function onLoaded() {
|
||||||
|
var h = document.querySelector('#main_layer').getBoundingClientRect().height + 'px'
|
||||||
editor = new toastui.Editor({
|
editor = new toastui.Editor({
|
||||||
el: document.querySelector('#editor'),
|
el: document.querySelector('#editor'),
|
||||||
|
height: '500px',
|
||||||
width:'100%',
|
width:'100%',
|
||||||
viewer: true,
|
viewer: true,
|
||||||
usageStatistics : false,
|
usageStatistics : false,
|
||||||
@ -135,15 +137,15 @@
|
|||||||
"> - **Embedded license files**: [jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt](jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt)\n" +
|
"> - **Embedded license files**: [jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt](jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt)\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\n"
|
"\n"
|
||||||
|
,
|
||||||
|
theme:"dark",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
<section class="wrapper style1">
|
<div id="main_layer" style="background:#30303594;">
|
||||||
<div class="container">
|
<div id="editor" ></div>
|
||||||
<div id="editor" ></div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</th:block>
|
</th:block>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -9,14 +9,10 @@
|
|||||||
<!-- Nav -->
|
<!-- Nav -->
|
||||||
<nav id="nav">
|
<nav id="nav">
|
||||||
<ul>
|
<ul>
|
||||||
<li id="menu_home" ><a th:href="@{/}">Home</a></li>
|
<li id="menu_home" class="current"><a th:href="@{/}">Home</a></li>
|
||||||
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
|
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
|
||||||
|
|
||||||
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
|
|
||||||
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
|
|
||||||
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
|
|
||||||
<li id="menu_drop">
|
<li id="menu_drop">
|
||||||
<a href="#">About</a>
|
<a href="#">Dropdown</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#">Lorem dolor</a></li>
|
<li><a href="#">Lorem dolor</a></li>
|
||||||
<li><a href="#">Magna phasellus</a></li>
|
<li><a href="#">Magna phasellus</a></li>
|
||||||
@ -31,9 +27,13 @@
|
|||||||
<li><a href="#">Veroeros feugiat</a></li>
|
<li><a href="#">Veroeros feugiat</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a th:href="@{/licenses}">Licenses</a></li>
|
<li><a href="#">Veroeros feugiat</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
|
||||||
|
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
|
||||||
|
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@ -19,26 +19,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
|
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
|
||||||
</div>
|
</div>
|
||||||
<div id="overlay" class="login_overlay">
|
|
||||||
<div id="popup" class="login_popup">
|
|
||||||
<div id="loginForm" class="login_form">
|
|
||||||
<h2>로그인</h2>
|
|
||||||
<form id="loginFormElement" onsubmit="return false;">
|
|
||||||
<input type="text" th:data="${enc}" id="loginId" placeholder="아이디" required>
|
|
||||||
<input type="password" th:data="${type}" id="loginPassword" placeholder="비밀번호" required>
|
|
||||||
<button type="submit" class="button">로그인</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="signupForm" class="login_form">
|
|
||||||
<h2>회원가입</h2>
|
|
||||||
<input type="text" placeholder="아이디" required>
|
|
||||||
<input type="password" placeholder="비밀번호" required>
|
|
||||||
<input type="email" placeholder="이메일" required>
|
|
||||||
<button onclick="submitForm('signup')">가입하기</button>
|
|
||||||
</div>
|
|
||||||
<span class="login_close" onclick="closePopup()">×</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script th:src="@{/assets/js/jquery.min.js}"></script>
|
<script th:src="@{/assets/js/jquery.min.js}"></script>
|
||||||
<script th:src="@{/assets/js/jquery.dropotron.min.js}"></script>
|
<script th:src="@{/assets/js/jquery.dropotron.min.js}"></script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user