init(frontend): add frontend server
also add static files and auth page
This commit is contained in:
parent
cb14672113
commit
37d40497d1
16
web/server/handlers.go
Normal file
16
web/server/handlers.go
Normal file
@ -0,0 +1,16 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func root(c *gin.Context) {
|
||||
authorized := c.GetBool("authorized")
|
||||
if authorized {
|
||||
c.HTML(http.StatusOK, "quotes.html", nil)
|
||||
} else {
|
||||
c.HTML(http.StatusOK, "auth.html", nil)
|
||||
}
|
||||
}
|
||||
25
web/server/server.go
Normal file
25
web/server/server.go
Normal file
@ -0,0 +1,25 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/H1K0/SkazaNull/api"
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/sessions/cookie"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Serve(addr string) {
|
||||
r := gin.Default()
|
||||
|
||||
store := cookie.NewStore([]byte("secret"))
|
||||
store.Options(sessions.Options{Path: "/"})
|
||||
r.Use(sessions.Sessions("session", store))
|
||||
|
||||
api.RegisterRoutes(r)
|
||||
|
||||
r.LoadHTMLGlob("templates/*.html")
|
||||
|
||||
r.Static("/static", "./static")
|
||||
r.GET("/", api.MiddlewareAuth, root)
|
||||
|
||||
r.Run(addr)
|
||||
}
|
||||
9
web/static/css/font-awesome.6.4.0.min.css
vendored
Normal file
9
web/static/css/font-awesome.6.4.0.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
11
web/static/css/tailwind-custom.css
Normal file
11
web/static/css/tailwind-custom.css
Normal file
@ -0,0 +1,11 @@
|
||||
/* 自定义媒体查询设置根字体大小 */
|
||||
@media (max-width: 640px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@media (width>640px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
16
web/static/js/auth.js
Normal file
16
web/static/js/auth.js
Normal file
@ -0,0 +1,16 @@
|
||||
$("#auth").on("submit", function (e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
url: "/api/auth",
|
||||
type: "POST",
|
||||
data: $("#auth").serialize(),
|
||||
dataType: "json",
|
||||
success: function (resp) {
|
||||
location.reload();
|
||||
},
|
||||
error: function (err) {
|
||||
$("#error-message").text(err.responseJSON.error);
|
||||
$("#error").removeClass("hidden");
|
||||
},
|
||||
});
|
||||
});
|
||||
2
web/static/js/jquery-3.6.0.min.js
vendored
Normal file
2
web/static/js/jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/static/js/tailwind-config.min.js
vendored
Normal file
1
web/static/js/tailwind-config.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
66
web/static/js/tailwind.3.4.5.es
Normal file
66
web/static/js/tailwind.3.4.5.es
Normal file
File diff suppressed because one or more lines are too long
BIN
web/static/webfonts/fa-brands-400.woff2
Normal file
BIN
web/static/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
web/static/webfonts/fa-solid-900.ttf
Normal file
BIN
web/static/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
web/static/webfonts/fa-solid-900.woff2
Normal file
BIN
web/static/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
75
web/templates/auth.html
Normal file
75
web/templates/auth.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
{{ template "head" . }}
|
||||
<title>Авторизация | SkazaNull</title>
|
||||
</head>
|
||||
|
||||
<body class="min-h-screen bg-gray-50 flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-xl w-full space-y-8 bg-white p-10 rounded-lg shadow-lg">
|
||||
<div class="text-center">
|
||||
<i class="fas fa-quote-left text-4xl text-custom mb-4"></i>
|
||||
<h2 class="mt-6 text-3xl font-bold font-['Playfair_Display'] text-gray-900">Категорически приветствую!</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 font-['Inter']">"Пацанский веб-сервис для пацанских цитат"</p>
|
||||
</div>
|
||||
<div id="error" class="hidden mt-4 p-4 rounded-md bg-red-50 border border-red-200 animate-fade-in"
|
||||
style="position: relative; transition: all 0.3s ease-in-out;">
|
||||
<p class="text-sm text-red-600 font-['Inter']">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-exclamation-circle text-red-500 mr-2"></i>
|
||||
<span class="text-sm text-red-600 font-["Inter"]" id="error-message">
|
||||
Упс, чёто пошло не так...
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
<button class="absolute top-2 right-2 text-red-400 hover:text-red-600" onclick="this.parentElement.style.display='none'">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<form class="mt-8 space-y-6" id="auth" action="/api/auth" method="POST">
|
||||
<div class="space-y-5">
|
||||
<div>
|
||||
<label for="login" class="block text-sm font-medium text-gray-700 font-['Inter']">
|
||||
Электронная почта
|
||||
</label>
|
||||
<div class="mt-1 relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<i class="fas fa-envelope text-gray-400"></i>
|
||||
</div>
|
||||
<input id="login" name="login" type="login" required placeholder="Логин"
|
||||
class="!rounded-button appearance-none block w-full pl-10 pr-3 py-2 border border-gray-300 shadow-sm placeholder-gray-400 focus:outline-none focus:ring-custom focus:border-custom sm:text-sm font-['Inter']" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-gray-700 font-['Inter']">
|
||||
Пароль
|
||||
</label>
|
||||
<div class="mt-1 relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<i class="fas fa-lock text-gray-400"></i>
|
||||
</div>
|
||||
<input id="password" name="password" type="password" required placeholder="Пароль"
|
||||
class="!rounded-button appearance-none block w-full pl-10 pr-3 py-2 border border-gray-300 shadow-sm placeholder-gray-400 focus:outline-none focus:ring-custom focus:border-custom sm:text-sm font-['Inter']" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit"
|
||||
class="!rounded-button group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium text-white bg-custom hover:bg-custom/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-custom font-['Inter']">
|
||||
Войти
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="text-center">
|
||||
<p class="text-xs text-gray-500 font-['Inter']">
|
||||
<i class="fas fa-quote-right text-custom mr-1"></i>
|
||||
© Masahiko AMANO (H1K0), 2025—present
|
||||
<i class="fas fa-quote-left text-custom ml-1"></i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/js/auth.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
10
web/templates/head.html
Normal file
10
web/templates/head.html
Normal file
@ -0,0 +1,10 @@
|
||||
{{ define "head" }}
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
|
||||
<link href="/static/css/font-awesome.6.4.0.min.css" rel="stylesheet"/>
|
||||
<link href="/static/css/tailwind-custom.css" rel="stylesheet"/>
|
||||
<script src="/static/js/tailwind.3.4.5.es"></script>
|
||||
<script src="/static/js/tailwind-config.min.js" data-color="#000000" data-border-radius="small"></script>
|
||||
<script src="/static/js/jquery-3.6.0.min.js"></script>
|
||||
{{ end }}
|
||||
Loading…
x
Reference in New Issue
Block a user