1549469775 3 years ago
parent
commit
413b34a93d
  1. 74049
      log/SQL.log
  2. 77
      packages/hapi-router/dist/hapi-router.cjs.js
  3. 2
      packages/hapi-router/dist/hapi-router.cjs.js.map
  4. 5
      packages/hapi-router/dist/index.d.ts
  5. 87
      packages/hapi-router/src/index.ts
  6. 2
      packages/hapi-router/src/util/decorators.ts
  7. 420
      public/login/css/style.css
  8. BIN
      public/login/fonts/FontAwesome.otf
  9. BIN
      public/login/fonts/fontawesome-webfont.eot
  10. 2671
      public/login/fonts/fontawesome-webfont.svg
  11. BIN
      public/login/fonts/fontawesome-webfont.ttf
  12. BIN
      public/login/fonts/fontawesome-webfont.woff
  13. BIN
      public/login/fonts/fontawesome-webfont.woff2
  14. 1
      public/login/images/image.svg
  15. 4
      public/login/js/jquery.min.js
  16. 36
      route.txt
  17. 11
      source/plugins/index.ts
  18. 0
      source/route/api/v1/upload/_upload.ts
  19. 0
      source/route/api/v1/upload/index.ts
  20. 0
      source/route/api/v1/user/_doc.md
  21. 2
      source/route/api/v1/user/index.ts
  22. 7
      source/route/index/color.ts
  23. 28
      source/route/views/index/index.ts
  24. 30
      source/route/views/login.ts
  25. 0
      source/route/views/nav/index.ts
  26. 1
      source/run.ts
  27. 2
      template/layout/layout.ejs
  28. 7
      template/layout/layout.pug
  29. 6
      template/views/about.ejs
  30. 2
      template/views/include/footer.ejs
  31. 9
      template/views/include/header.ejs
  32. 124
      template/views/login.ejs

74049
log/SQL.log

File diff suppressed because it is too large

77
packages/hapi-router/dist/hapi-router.cjs.js

@ -189,16 +189,28 @@ function swagger(desc, notes, tags) {
var path = require("path");
var fs = require("fs");
var routes = ["所有路由路径:"];
var routePlugin = (function () {
function routePlugin() {
this.name = "routePlugin";
this.version = "0.0.1";
}
routePlugin.prototype.register = function (server, options) {
var sourceDir = options.sourceDir;
var type = options.type || "jwt";
routePlugin.prototype.register = function (server, opts) {
var sourceDir = opts.sourceDir;
var type = opts.type || "jwt";
var array = [];
for (var i = 0; i < sourceDir.length; i++) {
var dir = sourceDir[i];
console.log(dir);
array.push(dir.dir + "对应路径:");
array = array.concat(this.registerRoute(server, dir.dir, dir.prefix || "", type));
}
fs.writeFileSync(path.resolve(process.cwd(), "route.txt"), array.join("\n"), {
encoding: "utf-8",
});
};
routePlugin.prototype.registerRoute = function (server, sourceDir, prefix, type) {
var files = walkDir(sourceDir);
var routes = [];
files.forEach(function (file) {
var e_1, _a;
var filename = file.relativeFileNoExt;
@ -234,26 +246,32 @@ var routePlugin = (function () {
}
}
route = removeIndex(route);
var options_1 = ff.$options ? ff.$options : {};
if (!options_1.auth) {
var options = ff.$options ? ff.$options : {};
if (!options.auth) {
if (ff.$auth == undefined) {
if (route.startsWith("/api")) {
options_1.auth = type;
options.auth = type;
}
else {
options_1.auth = false;
options.auth = false;
}
}
else if (ff.$auth) {
options_1.auth = type;
options.auth =
typeof ff.$auth === "boolean"
? type
: {
strategy: type,
mode: ff.$auth,
};
}
else {
options_1.auth = false;
options.auth = false;
}
}
if (!options_1.validate) {
if (!options.validate) {
var validateObj = ff.$validate || {};
if (options_1.auth && type === "jwt") {
if (options.auth && type === "jwt") {
if (validateObj.headers) {
validateObj.headers = validateObj.headers.keys({
Authorization: Joi__namespace.string(),
@ -268,27 +286,42 @@ var routePlugin = (function () {
}
}
if (validateObj) {
options_1.validate = validateObj;
options.validate = validateObj;
}
}
if (ff.$swagger) {
options_1.description = ff.$swagger[0];
options_1.notes = ff.$swagger[1];
options_1.tags = ff.$swagger[2];
options.description = ff.$swagger[0];
options.notes = ff.$swagger[1];
options.tags = ff.$swagger[2];
}
route = prefix ? (route[0] + prefix + "/" + route.slice(1)) : route;
var str = route;
if (options_1.auth) {
str = " 需要权限: " + " " + full(method) + " " + str;
if ((typeof options.auth === "string" && options.auth) ||
(typeof options.auth === "object" &&
options.auth.mode === "required")) {
str =
" 需要权限 : " + " " + full(method) + " " + str;
}
else if (typeof options.auth === "object" &&
options.auth.mode === "optional") {
str =
" 不需权限(提供即需验证): " + " " + full(method) + " " + str;
}
else if (typeof options.auth === "object" &&
options.auth.mode === "try") {
str =
" 不需权限(提供无需验证): " + " " + full(method) + " " + str;
}
else {
str = " 不需权限: " + " " + full(method) + " " + str;
str =
" 不需权限 : " + " " + full(method) + " " + str;
}
routes.push(str);
server.route({
method: method,
path: route,
handler: ff,
options: options_1,
options: options,
});
}
}
@ -302,9 +335,7 @@ var routePlugin = (function () {
}
}
});
fs.writeFileSync(path.resolve(process.cwd(), "route.txt"), routes.join("\n"), {
encoding: "utf-8",
});
return routes;
};
return routePlugin;
}());

2
packages/hapi-router/dist/hapi-router.cjs.js.map

File diff suppressed because one or more lines are too long

5
packages/hapi-router/dist/index.d.ts

@ -4,7 +4,8 @@ declare module '@noderun/hapi-router' {
class routePlugin {
name: string;
version: string;
register(server: any, options: any): void;
register(server: any, opts: any): void;
registerRoute(server: any, sourceDir: any, prefix: any, type: any): any[];
}
const plugin: routePlugin;
export { plugin };
@ -15,7 +16,7 @@ declare module '@noderun/hapi-router/util/decorators' {
export function method(opts?: string | Array<string>): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function route(route?: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function config(options: Object): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function auth(isAuth?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function auth(isAuth?: boolean | "try" | "required" | "optional"): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function validate(validate: Object): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
export function swagger(desc: any, notes: any, tags: any): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
}

87
packages/hapi-router/src/index.ts

@ -2,19 +2,35 @@
import { walkDir, removeIndex, isIndexEnd } from "./util";
import * as Joi from "joi";
const path = require("path")
const fs = require("fs")
const routes = ["所有路由路径:"];
const path = require("path");
const fs = require("fs");
class routePlugin {
public name: string = "routePlugin";
public version: string = "0.0.1";
public register(server: any, options: any) {
const sourceDir = options.sourceDir;
const type = options.type || "jwt";
public register(server: any, opts: any) {
const sourceDir = opts.sourceDir;
const type = opts.type || "jwt";
let array = [];
for (let i = 0; i < sourceDir.length; i++) {
const dir = sourceDir[i];
console.log(dir);
array.push(dir.dir + "对应路径:");
array = array.concat(
this.registerRoute(server, dir.dir, dir.prefix || "", type)
);
}
fs.writeFileSync(
path.resolve(process.cwd(), "route.txt"),
array.join("\n"),
{
encoding: "utf-8",
}
);
}
registerRoute(server, sourceDir, prefix, type) {
const files = walkDir(sourceDir);
const routes = [];
files.forEach((file) => {
let filename = file.relativeFileNoExt;
let array = filename.split(path.sep).slice(1);
@ -56,24 +72,30 @@ class routePlugin {
options.auth = false;
}
} else if (ff.$auth) {
options.auth = type;
options.auth =
typeof ff.$auth === "boolean"
? type
: {
strategy: type,
mode: ff.$auth,
};
} else {
options.auth = false;
}
}
if (!options.validate) {
let validateObj = ff.$validate || {};
if(options.auth&&type === "jwt"){
if (options.auth && type === "jwt") {
if (validateObj.headers) {
validateObj.headers = validateObj.headers.keys({
Authorization: Joi.string(),
})
}else{
});
} else {
validateObj.headers = Joi.object({
headers: Joi.object({
Authorization: Joi.string(),
}).unknown(), // 注意加上这个
})
});
}
}
if (validateObj) {
@ -86,11 +108,30 @@ class routePlugin {
options.notes = ff.$swagger[1];
options.tags = ff.$swagger[2];
}
route = prefix ? (route[0] + prefix + "/" + route.slice(1)) : route
let str = route;
if (options.auth) {
str = " 需要权限: "+ " "+full(method)+" " + str;
if (
(typeof options.auth === "string" && options.auth) ||
(typeof options.auth === "object" &&
options.auth.mode === "required")
) {
str =
" 需要权限 : " + " " + full(method) + " " + str;
} else if (
typeof options.auth === "object" &&
options.auth.mode === "optional"
) {
str =
" 不需权限(提供即需验证): " + " " + full(method) + " " + str;
} else if (
typeof options.auth === "object" &&
options.auth.mode === "try"
) {
str =
" 不需权限(提供无需验证): " + " " + full(method) + " " + str;
} else {
str = " 不需权限: "+ " "+full(method)+" " + str;
str =
" 不需权限 : " + " " + full(method) + " " + str;
}
routes.push(str);
server.route({
@ -103,17 +144,15 @@ class routePlugin {
}
}
});
fs.writeFileSync(path.resolve(process.cwd(), "route.txt"), routes.join("\n"), {
encoding: "utf-8",
});
return routes;
}
}
function full(str: string, length=10) {
let len = str.length;
let need = length - len;
if(need <= 0) return str
return str+[...Array(need)].map((v,i)=>" ").join("")
function full(str: string, length = 10) {
let len = str.length;
let need = length - len;
if (need <= 0) return str;
return str + [...Array(need)].map((v, i) => " ").join("");
}
const plugin = new routePlugin();

2
packages/hapi-router/src/util/decorators.ts

@ -17,7 +17,7 @@ export function config(options:Object) {
}
}
export function auth(isAuth:boolean = true) {
export function auth(isAuth:boolean | "try" | "required" | "optional" = true) {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
target[propertyKey].$auth = isAuth
}

420
public/login/css/style.css

@ -0,0 +1,420 @@
/*
Author: W3layouts
Author URL: http://w3layouts.com
*/
html {
scroll-behavior: smooth;
}
body,
html {
margin: 0;
padding: 0;
font-family: 'Poppins', sans-serif;
}
* {
box-sizing: border-box;
}
.d-grid {
display: grid;
}
.d-flex {
display: flex;
display: -webkit-flex;
}
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
button,
input,
select {
-webkit-appearance: none;
outline: none;
font-family: 'Poppins', sans-serif;
}
button,
.btn,
select {
cursor: pointer;
}
a {
text-decoration: none;
}
img {
max-width: 100%;
}
ul {
margin: 0;
padding: 0
}
h1,
h2,
h3,
h4,
h5,
h6,
p {
margin: 0;
padding: 0
}
p {
color: #666;
font-size: 16px;
line-height: 25px;
opacity: .6;
}
.p-relative {
position: relative;
}
.p-absolute {
position: absolute;
}
.p-fixed {
position: fixed;
}
.p-sticky {
position: sticky;
}
.btn,
button,
.actionbg,
input {
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-o-border-radius: 4px;
-ms-border-radius: 4px;
}
.btn:hover,
button:hover {
transition: 0.5s ease;
-webkit-transition: 0.5s ease;
-o-transition: 0.5s ease;
-ms-transition: 0.5s ease;
-moz-transition: 0.5s ease;
}
/*-- wrapper start --*/
.wrapper {
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
@media (min-width: 576px) {
.wrapper {
max-width: 540px;
}
}
@media (min-width: 768px) {
.wrapper {
max-width: 720px;
}
}
@media (min-width: 992px) {
.wrapper {
max-width: 960px;
}
}
@media (min-width: 1200px) {
.wrapper {
max-width: 1140px;
}
}
.wrapper-full {
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
/*-- //wrapper start --*/
/*-- form styling --*/
.w3l-mockup-form {
position: relative;
min-height: 100vh;
z-index: 0;
background: rgba(99, 194, 110, 0.1);
padding: 40px 40px;
justify-content: center;
display: grid;
grid-template-rows: 1fr auto 1fr;
align-items: center;
}
.container {
max-width: 890px;
margin: 0 auto;
}
.w3l_form {
padding: 0px;
flex-basis: 50%;
-webkit-flex-basis: 50%;
background: #00c16e;
padding: 100px 50px;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
.content-wthree {
flex-basis: 60%;
-webkit-flex-basis: 60%;
box-sizing: border-box;
padding: 3em 3.5em;
background: #fff;
box-shadow: 2px 9px 49px -17px rgba(0, 0, 0, 0.1);
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
.w3l-workinghny-form .logo {
text-align: center;
}
.w3l-mockup-form .main-mockup {
position: relative;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
margin: 40px 0;
}
.w3l-mockup-form .alert-close {
cursor: pointer;
height: 35px;
width: 35px;
line-height: 35px;
position: absolute;
right: -5px;
top: -5px;
background: #62c16e;
border-radius: 50px;
color: #fff;
text-align: center;
}
.w3l-mockup-form form {
margin-top: 30px;
margin-bottom: 30px;
}
.social-icons {
text-align: center;
}
.w3l-mockup-form h1 {
text-align: center;
font-size: 40px;
font-weight: 500;
color: #3b3663;
}
.w3l-mockup-form h2 {
display: inline-block;
font-size: 25px;
line-height: 35px;
margin-bottom: 5px;
font-weight: 600;
color: #3b3663;
}
.w3l-mockup-form input[type="text"],
.w3l-mockup-form input[type="email"] {
outline: none;
margin-bottom: 15px;
font-size: 16px;
color: #999;
text-align: left;
padding: 14px 20px;
width: 100%;
display: inline-block;
box-sizing: border-box;
border: none;
outline: none;
background: transparent;
border: 1px solid #e5e5e5;
}
.w3l-mockup-form button {
font-size: 18px;
color: #fff;
width: 100%;
background: #00c16e;
border: none;
padding: 14px 15px;
font-weight: 500;
transition: .3s ease;
-webkit-transition: .3s ease;
-moz-transition: .3s ease;
-ms-transition: .3s ease;
-o-transition: .3s ease;
}
.w3l-mockup-form button:hover {
background: #4ca356;
}
.w3l-mockup-form .social-icons ul li {
list-style: none;
display: inline-block;
}
.w3l-mockup-form .social-icons ul li a {
padding: 8px;
}
.w3l-mockup-form .social-icons ul li a:hover {
opacity: 0.8;
transition: 0.5s ease;
-webkit-transition: 0.5s ease;
-o-transition: 0.5s ease;
-ms-transition: 0.5s ease;
-moz-transition: 0.5s ease;
}
.w3l-mockup-form .social-icons ul span.fa {
color: #696687;
font-size: 18px;
opacity: .8;
}
.w3l-mockup-form .social-icons ul li a.facebook span {
color: #3b5998;
}
.w3l-mockup-form .social-icons ul li a.twitter span {
color: #1da1f2;
}
.w3l-mockup-form .social-icons ul li a.pinterest span {
color: #e60023;
}
.copyright p {
text-align: center;
font-size: 17px;
line-height: 26px;
color: #607863;
opacity: 1;
}
p.copy-footer-29 a {
color: #517856;
}
p.copy-footer-29 a:hover {
color: #00c16e;
transition: 0.5s ease;
-webkit-transition: 0.5s ease;
-o-transition: 0.5s ease;
-ms-transition: 0.5s ease;
-moz-transition: 0.5s ease;
}
/*-- responsive design --*/
@media (max-width:736px) {
.w3l-mockup-form .main-mockup {
flex-direction: column;
}
.w3l_form {
order: 2;
padding: 50px;
border-radius: 0;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.content-wthree {
order: 1;
border-radius: 0;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
}
@media (max-width:568px) {
.w3l-mockup-form h1 {
font-size: 30px;
}
.w3l-mockup-form .main-mockup {
margin: 30px 0;
}
.content-wthree {
padding: 2.5em;
}
}
@media (max-width: 415px) {
.w3l-mockup-form {
padding: 40px 30px;
}
}
@media (max-width:384px) {
.w3l-mockup-form {
padding: 30px 15px;
}
.content-wthree {
padding: 2em;
}
.w3l-mockup-form h1 {
font-size: 28px;
}
.w3l-mockup-form h2 {
font-size: 22px;
line-height: 32px;
}
.copyright p {
font-size: 16px;
}
}
/*-- //responsive design --*/
/*-- //form styling --*/

BIN
public/login/fonts/FontAwesome.otf

Binary file not shown.

BIN
public/login/fonts/fontawesome-webfont.eot

Binary file not shown.

2671
public/login/fonts/fontawesome-webfont.svg

File diff suppressed because it is too large

After

Width:  |  Height:  |  Size: 434 KiB

BIN
public/login/fonts/fontawesome-webfont.ttf

Binary file not shown.

BIN
public/login/fonts/fontawesome-webfont.woff

Binary file not shown.

BIN
public/login/fonts/fontawesome-webfont.woff2

Binary file not shown.

1
public/login/images/image.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.6 KiB

4
public/login/js/jquery.min.js

File diff suppressed because one or more lines are too long

36
route.txt

@ -1,18 +1,18 @@
所有路由路径:
权限: GET /api/upload
权限: POST /api/upload/upload
不需权限: POST /api/user/register
权限: POST /api/user/logout
不需权限: POST /api/user/login
需要权限: DELETE /api/user/del
权限: GET /api/user/userinfo
不需权限: GET /index/color
不需权限: GET /404
不需权限: GET /css
权限: GET /
不需权限: GET /login
不需权限: POST /login
不需权限: GET /about
需要权限: GET /docs/{path*}
不需权限: GET /{path*}
不需权限: GET /nav
D:\1XYX\demo\hapi-demo\source\route\api对应路径:
需权限 : GET /api/v1/upload
需权限 : POST /api/v1/upload/upload
不需权限 : POST /api/v1/user/register
需权限 : POST /api/v1/user/logout
不需权限 : POST /api/v1/user/login
需要权限 : DELETE /api/v1/user/del
需权限 : GET /api/v1/user/userinfo
D:\1XYX\demo\hapi-demo\source\route\views对应路径:
不需权限 : GET /404
不需权限 : GET /css
需权限(提供无需验证): GET /
不需权限 : GET /about
需要权限 : GET /docs/{path*}
不需权限 : GET /{path*}
不需权限(提供无需验证): GET /login
不需权限 : POST /login
不需权限 : GET /nav

11
source/plugins/index.ts

@ -10,7 +10,16 @@ export default [
{
plugin: routePlugin as Plugin<any>,
options: {
sourceDir: path.resolve(sourceDir, "route"),
sourceDir: [
{
dir: path.resolve(sourceDir, "route/api"),
prefix: "api"
},
{
dir: path.resolve(sourceDir, "route/views"),
prefix: ""
},
],
type: "session"
},
},

0
source/route/api/upload/_upload.ts → source/route/api/v1/upload/_upload.ts

0
source/route/api/upload/index.ts → source/route/api/v1/upload/index.ts

0
source/route/api/user/_doc.md → source/route/api/v1/user/_doc.md

2
source/route/api/user/index.ts → source/route/api/v1/user/index.ts

@ -72,7 +72,7 @@ export default class {
//===== session ===== Start
request.cookieAuth.set({ id: result.id });
//===== session ===== End
return gSuccess({ id: result.id });
return gSuccess({});
}
@method("DELETE")

7
source/route/index/color.ts

@ -1,7 +0,0 @@
export default class {
index(req, h){
}
}

28
source/route/index/index.ts → source/route/views/index/index.ts

@ -17,12 +17,7 @@ export default class Index {
return h.view("views/css.pug");
}
@auth()
@config({
auth: {
mode: "try",
},
})
@auth("try")
async index(request: Req, h: Res): ReturnValue {
if (request.auth.isAuthenticated) {
// 登录了
@ -31,27 +26,6 @@ export default class Index {
}
return h.view("views/index.pug", { ss: request.auth.isAuthenticated });
}
@method("GET")
@route("/login")
loginView(request, h) {
return h.view("views/login.ejs");
}
@method("POST")
@auth(false)
@route("/login")
async login(request: Req, h: Res): ReturnValue {
const { username, password } = request.payload as any;
const User = request.getModel("User");
const account = <any>await User.findOne({ where: { username: username } });
if (!account || !(await bcrypt.compare(password, account.password))) {
return h.redirect("/login");
}
request.cookieAuth.set({ id: account.id });
return h.redirect("/");
}
@route("/about")
@auth(false)

30
source/route/views/login.ts

@ -0,0 +1,30 @@
import { Req, Res, ReturnValue } from "#/global";
import { auth, config, method, route } from "@noderun/hapi-router";
import * as bcrypt from "bcrypt";
/**
*
*/
export default class {
@route("/index")
@auth("try")
@method("GET")
async loginView(request: Req, h: Res): ReturnValue {
return h.view("views/login.ejs");
}
@method("POST")
@route("/index")
@auth(false)
async loginRes(request: Req, h: Res): ReturnValue {
const { username, password } = request.payload as any;
const User = request.getModel("User");
const account = <any>await User.findOne({ where: { username: username } });
if (!account || !(await bcrypt.compare(password, account.password))) {
return h.redirect("/login");
}
request.cookieAuth.set({ id: account.id });
return h.redirect("/");
}
}

0
source/route/nav/index.ts → source/route/views/nav/index.ts

1
source/run.ts

@ -14,7 +14,6 @@ const run = async (): Promise<Server> => {
port: 3388,
host: "localhost",
});
await server.register([
{
plugin: require("hapi-sequelizejs"),

2
template/layout/layout.ejs

@ -1 +1,3 @@
11111111
<%- content %>
22222222

7
template/layout/layout.pug

@ -1,8 +1,7 @@
doctype html
html(lang="en")
html(lang="zh-cn")
block var
i
head
meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible", content="IE=edge")
@ -11,9 +10,7 @@ html(lang="en")
title #{title || 'WEB'}
link(rel="stylesheet", href="/public/css/common/style.css")
block head
i
body
block content
div no content
p no content
block script
i

6
template/views/about.ejs

@ -1,3 +1,3 @@
<div>
阿萨德 sad撒
</div>
<%- include("include/header", {title: "2131"}) %>
<div>撒大大大</div>
<%- include("include/footer") %>

2
template/views/include/footer.ejs

@ -0,0 +1,2 @@
</body>
</html>

9
template/views/include/header.ejs

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%- title || "WEB" %></title>
</head>
<body>

124
template/views/login.ejs

@ -1,6 +1,118 @@
<h3>Please Log In</h3>
<form method="post" action="/login">
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" value="Login" />
</form>
<!--
Author: W3layouts
Author URL: http://w3layouts.com
-->
<!DOCTYPE html>
<html lang="zxx">
<head>
<title>Well Subscribe form Responsive Widget Template : W3layouts</title>
<!-- Meta tag Keywords -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<meta
name="keywords"
content="Well Subscribe form Responsive web template, Bootstrap Web Templates, Flat Web Templates, Android Compatible web template, Smartphone Compatible web template, free webdesigns for Nokia, Samsung, LG, SonyEricsson, Motorola web design"
/>
<!-- //Meta tag Keywords -->
<link
href="//fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap"
rel="stylesheet"
/>
<!--/Style-CSS -->
<link rel="stylesheet" href="/public/login/css/style.css" type="text/css" media="all" />
<!--//Style-CSS -->
<script
src="https://kit.fontawesome.com/af562a2a63.js"
crossorigin="anonymous"
></script>
</head>
<body>
<!-- form section start -->
<section class="w3l-mockup-form">
<h1>天蚕 / 地缺</h1>
<div class="container">
<!-- /form -->
<div class="workinghny-form-grid">
<div class="main-mockup">
<div class="alert-close">
<span class="fa fa-close"></span>
</div>
<div class="w3l_form align-self">
<div class="left_grid_info">
<img src="/public/login/images/image.svg" alt="" />
</div>
</div>
<div class="content-wthree">
<h2>现在开始注册</h2>
<p>
lets keep in touch! Please subscribe to our newsletter and stay
updated
</p>
<form action="#" method="post">
<input
type="text"
class="text"
name="text"
placeholder="Enter Your Name"
required=""
/>
<input
type="email"
class="email"
name="email"
placeholder="Enter Your Email"
required=""
/>
<button class="btn" type="submit">Subscribe</button>
</form>
<div class="social-icons w3layouts">
<ul>
<li>
<a href="#url" class="facebook"
><span class="fab fa-facebook"></span>
</a>
</li>
<li>
<a href="#url" class="twitter"
><span class="fab fa-twitter"></span>
</a>
</li>
<li>
<a href="#url" class="pinterest"
><span class="fab fa-pinterest"></span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- //form -->
</div>
<!-- copyright-->
<div class="copyright text-center">
<p class="copy-footer-29">
© 2020 Well Subscribe form. All rights reserved | Design by
<a href="https://w3layouts.com">W3layouts</a>
</p>
</div>
<!-- //copyright-->
</section>
<!-- //form section start -->
<script src="/public/login/js/jquery.min.js"></script>
<script>
$(document).ready(function (c) {
$(".alert-close").on("click", function (c) {
$(".main-mockup").fadeOut("slow", function (c) {
$(".main-mockup").remove();
});
});
});
</script>
</body>
</html>

Loading…
Cancel
Save