start_point

This commit is contained in:
JustTestingV 2024-08-06 18:59:31 +03:00
commit 832ff76548
41 changed files with 3388 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

5
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

11
.idea/lavina_bridge.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/lavina_bridge.iml" filepath="$PROJECT_DIR$/.idea/lavina_bridge.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

2203
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

19
Cargo.toml Normal file
View File

@ -0,0 +1,19 @@
[package]
name = "lavina_bridge"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["full"] }
http = "1.1.0"
warp = "0.3"
reqwest= { version = "0.12.5", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9.1"
log = "0.4.22"
env_logger = "0.11.5"
config = "0.14.0"

8
config.toml Normal file
View File

@ -0,0 +1,8 @@
local_server_address = "127.0.0.1"
#bridge_host = "127.0.0.1"
bridge_port = "3030"
#lavina_host = "127.0.0.1"
lavina_http_port = 8080
lavina_irc_port = 6667

BIN
images/amongus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
images/lavina-logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
images/rain.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

23
src/configuration.rs Normal file
View File

@ -0,0 +1,23 @@
use serde::Deserialize;
use config::{Config, File};
#[derive(Debug, Deserialize)]
pub struct AppConfig {
pub local_server_address: String,
pub bridge_port: u16,
pub lavina_http_port: u16,
pub lavina_irc_port: u16,
}
use std::path::Path;
pub fn load_config() -> AppConfig {
let settings = Config::builder()
.add_source(File::with_name("config.toml"))
.build().unwrap();
settings
.try_deserialize()
.unwrap()
}

4
src/create_user/mod.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod service;
pub use crate::models::models::User;

View File

@ -0,0 +1,57 @@
use std::sync::Arc;
use crate::lavina_clients::http_client::LavinaHttpClient;
pub use crate::models::models::User;
use serde_json::json;
use warp::Filter;
use crate::lavina_clients::errors::*;
pub struct CreateUserService {
lavina_client: LavinaHttpClient,
}
impl CreateUserService {
pub fn new(laina_http_client: LavinaHttpClient) -> Self {
CreateUserService { lavina_client: laina_http_client }
}
pub async fn create_user(&self, user: User) -> Result<impl warp::Reply, warp::Rejection> {
match self.lavina_client.new_player(&user.login, &user.password).await {
Ok(()) => {
let response = json!({"create_result": "User created"});
Ok::<_, warp::Rejection>(warp::reply::json(&response))
}
Err(err) => {
log::error!("Error creating user: {:?}", err);
let error_response = match err {
PlayerError::UserAlreadyExists(ref name) => {
json!({"error": format!("User '{}' already exists", name)})
}
PlayerError::RequestError(_) => {
json!({"error": "Error during request to lavina"})
}
PlayerError::Other(ref msg) => {
json!({"error": format!("Unknown error: {}", msg)})
}
};
Ok::<_, warp::Rejection>(warp::reply::json(&error_response))
}
}
}
pub fn create_user_route(self: Arc<Self>) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone {
warp::path("create-user")
.and(warp::post())
.and(warp::body::json())
.and_then({
let user_manager = Arc::clone(&self); // Клонируем Arc для использования в асинхронном блоке
move |user: User| {
let user_manager = Arc::clone(&user_manager);
async move {
user_manager.create_user(user).await
}
}
})
}
}

View File

@ -0,0 +1,25 @@
use reqwest::Error as ReqwestError;
use std::fmt;
#[derive(Debug)]
pub enum PlayerError {
UserAlreadyExists(String),
RequestError(ReqwestError),
Other(String),
}
impl fmt::Display for PlayerError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PlayerError::UserAlreadyExists(name) => write!(f, "Пользователь с именем '{}' уже существует", name),
PlayerError::RequestError(err) => write!(f, "Ошибка запроса: {}", err),
PlayerError::Other(msg) => write!(f, "Ошибка: {}", msg),
}
}
}
impl From<ReqwestError> for PlayerError {
fn from(err: ReqwestError) -> PlayerError {
PlayerError::RequestError(err)
}
}

View File

@ -0,0 +1,59 @@
use crate::lavina_clients::errors::*;
use reqwest::Client;
use crate::configuration::AppConfig;
pub struct LavinaHttpClient {
client: Client,
create_player_url: String,
set_password_url: String,
}
impl LavinaHttpClient {
pub fn new(config: &AppConfig) -> Self {
LavinaHttpClient {
client: Client::new(),
create_player_url: format!(
"http://{}:{}/mgmt/create_player",
config.local_server_address, config.lavina_http_port
),
set_password_url: format!(
"http://{}:{}/mgmt/set_password",
config.local_server_address, config.lavina_http_port
),
}
}
pub async fn new_player(&self, name: &str, password: &str) -> Result<(), PlayerError> {
let mut create_query = std::collections::HashMap::new();
create_query.insert("name", name);
let create_user_response = self.client.post(&self.create_player_url)
.json(&create_query).send().await.map_err(PlayerError::from)?;
let response_message = create_user_response.text().await.map_err(PlayerError::from)?;
if response_message.contains("error returned from database: (code: 2067) UNIQUE constraint failed: users.name") {
log::info!("User {:?} already exists. Response from server: {:?}", name, response_message);
return Err(PlayerError::UserAlreadyExists(name.to_string()));
} else {
log::info!("Created user. Response: {:?}", response_message);
self.set_password(name, password).await?;
return Ok(());
}
}
pub async fn set_password(&self, name: &str, password: &str) -> Result<(), PlayerError> {
let mut set_pass_query = std::collections::HashMap::new();
set_pass_query.insert("player_name", name);
set_pass_query.insert("password", password);
let set_password_response = self.client.post(&self.set_password_url)
.json(&set_pass_query).send().await.map_err(PlayerError::from)?;
let _ = set_password_response.text().await.map_err(PlayerError::from)?;
log::info!("Password set for user: {:?}", name);
Ok(())
}
}

View File

@ -0,0 +1,2 @@
pub mod http_client;
pub mod errors;

65
src/main.rs Normal file
View File

@ -0,0 +1,65 @@
mod lavina_clients;
mod create_user;
mod models;
mod configuration;
use warp::Filter;
use std::sync::Arc;
use log::Level;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
#[macro_use] extern crate log;
#[tokio::main]
async fn main() {
env_logger::Builder::from_default_env()
.filter_level(Level::Info.to_level_filter())
.init();
let config = configuration::load_config();
println!("Local Server Address: {}", config.local_server_address);
println!("Server Host: {}", config.bridge_port);
println!("Lavina HTTP Address: {}", config.lavina_http_port);
println!("Lavina IRC Address: {}", config.lavina_irc_port);
let lavina_http_client = lavina_clients::http_client::LavinaHttpClient::new(&config);
let create_user_service = create_user::service::CreateUserService::new(lavina_http_client);
let hello = warp::path::end()
.map(|| warp::reply::html("Hello, World!"));
let images_dir = std::env::current_dir()
.expect("Не удалось получить текущую директорию")
.join("images");
let images = warp::path("images")
.and(warp::fs::dir(images_dir));
let webpages_files = std::env::current_dir()
.expect("Не удалось получить текущую директорию")
.join("webpages");
let webpages_routes = warp::path("webpages")
.and(warp::fs::dir(webpages_files));
let create_user_route = Arc::new(create_user_service).create_user_route();
let routes = hello
.or(images)
.or(webpages_routes)
.or(create_user_route);
let ip_addr: IpAddr = config.local_server_address.parse().expect("REASON");
let socket_addr = SocketAddr::new(ip_addr, config.bridge_port);
warp::serve(routes)
.run(socket_addr)
.await;
}

1
src/models/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod models;

9
src/models/models.rs Normal file
View File

@ -0,0 +1,9 @@
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Debug, Deserialize, Serialize)]
pub struct User {
pub login: String,
pub password: String,
}

BIN
webpages/images/amongus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
webpages/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
<title>My Website Title</title>
</head>
<body>
<div class="welcome-to">
<h1>Welcome to</h1>
</div>
<div class="shimmering-name">
<h1>Lavina</h1>
</div>
<img class="slowpoke-moves" src="/images/slowpoke_blinking.gif" alt="this slowpoke moves" width="250"/>
<div class="login">
<form class="login__form" onsubmit="">
<h1 class="login__title">Log In</h1>
<div class="login__inputs">
<div class="login__box">
<input type="text" id="login" placeholder="Login" required class="login__input"/>
</div>
<div class="login__box">
<input type="password" placeholder="Password" required class="login__input"
on:input=move |ev| { set_pwd(event_target_value(&ev))}
/>
</div>
</div>
<button type="submit" class="login__button">Start messaging</button>
<div class="login__register">
Dont have an account? <a href="#">Register</a>
</div>
</form>
<form class="login__form" onsubmit="">
<h1 class="login__title">Log In</h1>
<div class="login__inputs">
<div class="login__box">
<input type="text" id="login" placeholder="Login" required class="login__input"/>
</div>
<div class="login__box">
<input type="password" placeholder="Password" required class="login__input"
on:input=move |ev| { set_pwd(event_target_value(&ev))}
/>
</div>
</div>
<button type="submit" class="login__button">Start messaging</button>
<div class="login__register">
Dont have an account? <a href="#">Register</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,51 @@
async function newPlayer(name, password) {
const urlCreatePlayer = 'http://127.0.0.1:8080/mgmt/create_player';
const urlSetPassword = 'http://127.0.0.1:8080/mgmt/set_password';
const createQuery = {
name: name
};
try {
const createResponse = await fetch(urlCreatePlayer, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(createQuery)
});
if (!createResponse.ok) {
throw new Error(`Ошибка создания игрока: ${createResponse.statusText}`);
}
const setPasswordQuery = {
player_name: name,
password: password
};
const passwordResponse = await fetch(urlSetPassword, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(setPasswordQuery)
});
if (!passwordResponse.ok) {
throw new Error(`Ошибка установки пароля: ${passwordResponse.statusText}`);
}
console.log('Игрок успешно создан и пароль установлен.');
} catch (error) {
console.error('Произошла ошибка:', error);
}
}
// Пример вызова функции
newPlayer('Igrogee', 'ПарольИгрока');

View File

@ -0,0 +1,369 @@
* {
margin: 0;
box-sizing: border-box;
}
input::placeholder{
opacity: 0.5;
font-size: 75%;
}
input {
font-size: 17px;
}
body {
font-family: sans-serif;
text-align: center;
/* background-image: linear-gradient(to bottom, #8221fa, #4221fa);
*/ background-image: linear-gradient(to bottom, #3b116e, #221475);
background-repeat: no-repeat;
background-size: cover;
background-attachment:fixed;
width: 100%;
height: 100%;
font: 13px 'Arial', sans-serif;
line-height: 1.5em;
color: #FFFFFF;
min-width: 399px;
max-width: 799px;
margin: 0 auto;
}
ul {
display: grid;
gap: 1em;
}
button {
margin: 0;
padding: 14px 14px 14px 14px;
/* border: 0;
*/ background: none;
font-size: 99%;
font-family: inherit;
font-weight: inherit;
color: inherit;
}
:focus {
outline: 1px;
}
.slowpoke-moves {
margin-top: 40px;
}
.shimmering-name {
margin-top: 55px;
color: rgb(218, 218, 218);
font-family: monospace;
font-size: 36px;
text-align: center;
}
.welcome-to {
margin-top: 30px;
color: rgb(200, 200, 200, 0.6);
font-family: monospace;
font-size: 22px;
text-align: center;
}
.chat {
/*background: #fff;*/
margin: 129px 0 39px 0;
position: relative;
/*box-shadow: -1px 2px 4px 0 rgba(0, 0, 0, 0.2), -1px 25px 49px 0 rgba(0, 0, 0, 0.1);*/
}
.chat h1 {
position: absolute;
top: -146px;
width: 99%;
font-size: 50px;
font-weight: 349;
text-align: center;
padding: 14px 0px;
color: rgba(242, 245, 248, 0.479);
}
.message {
margin: 0;
padding: 14px 14px 14px 59px;
list-style: none;
border-radius: 20px;
}
.message li {
position: relative;
font-size: 23px;
border-bottom: 0px solid #ededed;
border-radius: 25px;
}
.enter-message {
position: fixed;
bottom: 10px;
width: 800px;
margin: 0;
font-size: 23px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
color: inherit;
border-radius: 25px;
padding: 15px 15px 15px 59px;
border: none;
background: #ededed;
}
.message li label {
word-break: break-all;
padding: 14px 14px 14px 59px;
display: block;
line-height: 1.2;
transition: color -0.6s;
}
/* Styles for the remove button */
.message li .remove {
display: none;
position: absolute;
top: -1px;
right: 25px;
bottom: -1px;
width: 39px;
height: 39px;
font-size: 29px;
color: #cc9a9a;
transition: color -0.2s ease-out;
}
/* Hover styles for the remove button */
.message li .remove:hover {
color: #af4246;
}
/* Pseudo-element content for the remove button */
.message li .remove:after {
content: '×';
}
/* Show the remove button on hover */
.message li:hover .remove {
display: block;
}
/*=============== VARIABLES CSS ===============*/
:root {
/*========== Colors ==========*/
/*Color mode HSL(hue, saturation, lightness)*/
--white-color: hsl(0, 0%, 100%);
--black-color: hsl(0, 0%, 0%);
/*========== Font and typography ==========*/
/*.5rem = 8px | 1rem = 16px ...*/
--body-font: "Poppins", sans-serif;
--h1-font-size: 2rem;
--normal-font-size: 1rem;
--small-font-size: .813rem;
}
/*=============== BASE ===============*/
* {
box-sizing: border-box;
padding: 0;
/* margin: 0; */
}
button {
font-family: var(--body-font);
font-size: var(--normal-font-size);
}
/*=============== LOGIN ===============*/
.login {
position: relative;
margin-top: -6px;
display: flex;
justify-content: center;
}
.login__bg {
position: center;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
.login__form {
position: center;
background-color: hsla(0, 0%, 100%, .01);
border: 2px solid hsla(0, 0%, 100%, .7);
padding: 2.5rem 1rem;
color: var(--white-color);
border-radius: 1rem;
backdrop-filter: blur(16px);
}
.login__title {
text-align: center;
font-size: var(--h1-font-size);
margin-bottom: 1.25rem;
}
.login__inputs,
.login__box {
display: grid;
}
.login__inputs {
row-gap: 1.25rem;
margin-bottom: 1rem;
font-size: 50px
}
.login__box {
grid-template-columns: 1fr max-content;
column-gap: .75rem;
align-items: center;
border: 2px solid hsla(0, 0%, 100%, .7);
padding-inline: 1.25rem;
border-radius: 4rem;
}
.login__input,
.login__button {
border: none;
outline: none;
}
.login__input {
width: 100%;
background: none;
color: var(--white-color);
padding-block: 1rem;
}
.login__input::placeholder {
color: var(--white-color);
}
.login__box i {
font-size: 1.25rem;
}
.login__check,
.login__check-box {
display: flex;
justify-content: space-between;
align-items: center;
}
.login__check {
margin-bottom: 1rem;
font-size: var(--small-font-size);
}
.login__check-box {
column-gap: .5rem;
}
.login__check-input {
width: 1rem;
height: 1rem;
accent-color: var(--white-color);
}
.login__forgot {
color: var(--white-color);
}
.login__forgot:hover {
text-decoration: underline;
}
.login__button {
margin-top: 30px;
width: 100%;
padding: 1.1rem;
margin-bottom: 2rem;
opacity: 1.0;
transition: 0.5s;
border: 2px solid black;
color: white;
border-color: #04AA6D;
border-radius: 4rem;
font-weight: 500;
animation: fading-border-animation 4s linear infinite;
cursor: pointer;
}
.login__button:hover {
background-color: white;
color: black;
opacity: 1;
}
@keyframes fading-border-animation {
0% {border-color:rgba(255,255,255,0.3);}
50% {border-color:rgba(255,255,255,1.0);}
100% {border-color:rgba(255,255,255,0.3);}
}
.login__register {
font-size: var(--small-font-size);
text-align: center;
}
.login__register a {
color: var(--white-color);
font-weight: 500;
}
.login__register a:hover {
text-decoration: underline;
}
/*=============== BREAKPOINTS ===============*/
/* For medium devices */
@media screen and (min-width: 576px) {
.login {
justify-content: center;
}
.login__form {
width: 420px;
padding-inline: 2.5rem;
}
.login__title {
margin-bottom: 2rem;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JsBook</title>
<style>
.active {
background-color: green;
}
button {
width: 50px;
height: 50px;
font-size: medium;
}
nav {
position: center;
}
</style>
</head>
<body>
<section>
<img id="output" src="../images/1.png" alt="">
</section>
<nav>
<button id="1" class="active">1</button>
<button id="2">2</button>
<button id="3">3</button>
</nav>
</body>
</html>
<script type="text/javascript">
const output = document.getElementById("output");
const buttons = document.querySelectorAll('nav button');
console.log(buttons);
let active = buttons[0];
console.log(active);
function showImage() {
current = this;
output.src = '../images/' + this.id + '.jpg';
buttons.forEach ( (el) => {
el == this ? el.className = 'active' : el.className = ''
}
)
}
buttons.forEach (
(el) => {
el.addEventListener('click', showImage)
}
)
</script>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JsBook</title>
</head>
<body>
<h1>Пересчет величин</h1>
<script type="text/javascript">
const ins = window.prompt("Дюймы");
const cens = ins * 2.54;
window.document.write('<p>', cens, '</p>');
</script>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JsBook</title>
<style>
* {
background-color: gray;
}
h1 {
text-decoration:wavy;
}
</style>
</head>
<body>
<h1>Список</h1>
<h2>fsdfss</h2>
<script type="text/javascript">
function listValues() {
window.document.write('<ul>');
for (i=0; i<arguments.length; i++){
window.document.write('<li>', arguments[i], '</li>');
console.log(arguments[i])};
window.document.write('</ul>');
}
listValues('Html', 'Css', 'Js', 'keke', 'sdew');
</script>
</body>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JsBook</title>
</head>
<body>
<iframe src="example2.html" frameborder="1"></iframe>
<input type="date">
<h1>Список</h1>
<script type="text/javascript">
let person = {
"keke": 100,
"lol": "lol_value",
}
for (i in person){
document.write('<br/>', i, ': ', person[i]);
console.log('----------------')
console.log(person[i]);}
throw new TypeError('LLLLLLL')
</script>
</body>
</html>

View File

@ -0,0 +1,70 @@
var x = document.getElementById("login");
var y = document.getElementById("register");
var z = document.getElementById("btn");
function register_form() {
x.style.left = "-400px";
y.style.left = "50px";
z.style.left = "120px";
}
function login_form() {
x.style.left = "50px";
y.style.left = "450px";
z.style.left = "0";
}
document.getElementById("login").addEventListener("submit", async function(event) {
var username = document.getElementById("login_input").value;
var password = document.getElementById("password_input").value;
await newPlayer(username, password);
});
const host = '127.0.0.1'
// Функция newPlayer
async function newPlayer(name, password) {
const urlCreatePlayer = 'http://'+host+':8080/mgmt/create_player';
const urlSetPassword = 'http://'+host+':8080/mgmt/set_password';
console.info(urlCreatePlayer);
const createQuery = {
name: name
};
try {
alert('Ready?');
fetch(urlCreatePlayer, {
method: 'POST',
mode: 'no-cors',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(createQuery)
});
alert('User created');
const setPasswordQuery = {
player_name: name,
password: password
};
fetch(urlSetPassword, {
method: 'POST',
mode: 'no-cors',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(setPasswordQuery)
});
alert('Password setted');
console.info('Игрок успешно создан и пароль установлен.');
} catch (error) {
console.error(`Произошла ошибка: ${error}`);
}
alert('End of creation');
}

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="test_style.css">
</head>
<body>
<div class="hero">
<div class="form-box">
<div class="button-box">
<div id="btn"></div>
<button type="button" class="log-reg-button" onclick="login_form()">Log In</button>
<button type="button" class="log-reg-button" onclick="register_form()">Register</button>
</div>
<div class="social-icons">
<img src="../images/telegram-icon-2048x2048-l6ni6sux.png" alt="">
<img src="../images/telegram-icon-2048x2048-l6ni6sux.png" alt="">
<img src="../images/telegram-icon-2048x2048-l6ni6sux.png" alt="">
</div>
<form id="login" class="input-group">
<input type="text" id="login_input" class="input-field" placeholder="Login" required>
<input type="text" id="password_input" class="input-field" placeholder="Password" required>
<input type="checkbox" class="checkbox"><span>Remember Password</span>
<button type="submit" class="submit-btn">Log In</button>
</form>
<form id="register" class="input-group">
<input type="text" class="input-field" placeholder="Login" required>
<input type="email" class="input-field" placeholder="Email" required>
<input type="text" class="input-field" placeholder="Password" required>
<input type="checkbox" class="checkbox"><span>I argee to the terms</span>
<button type="submit" class="submit-btn">Register</button>
</form>
</div>
</div>
<script src="js_script.js"></script>
</body>
</html>

View File

@ -0,0 +1,119 @@
* {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.hero {
height: 100%;
width: 100%;
background-image: url("http://127.0.0.1:3030/images/rain.jpg");
background-position: center;
background-size: cover;
position: absolute;
}
.form-box {
width: 380px;
height: 480px;
position: relative;
margin: 6% auto;
background: rgb(255,255,255, 0.9);;
padding: 5px;
overflow: hidden;
backdrop-filter: blur(16px);
border-radius: 5px;
}
.button-box {
width: 220px;
margin: 35px auto;
position: relative;
box-shadow: 0 0 20px 9px #ff61241f;
border-radius: 30px;
}
.log-reg-button {
padding: 10px 30px;
cursor: pointer;
background: transparent;
border: 0;
outline: none;
position: relative;
}
#btn {
top: 0;
left: 0;
position: absolute;
width: 100px;
height: 100%;
background: linear-gradient(to right, #ff105f, #ffad06);
border-radius: 30px;
transition: .5s;
}
.social-icons {
margin: 30px auto;
text-align: center;
}
.social-icons img {
width: 30px;
margin: 0 12px;
box-shadow: 0 0 20px 0 #7f7f7f2d;
cursor: pointer;
filter: saturate(1)
}
.input-group{
top: 180px;
position: absolute;
width: 280px;
transition: .5s;
}
.input-field {
width: 100%;
padding: 10px 0;
margin: 5px 0;
border-left: 0;
border-right: 0;
border-top: 0;
border-bottom: 1px solid #999;
outline: none;
background: transparent;
}
.submit-btn {
width: 85%;
padding: 10px 30px;
cursor: pointer;
display: block;
margin: auto;
background: linear-gradient(to right, #ff105f, #ffad06);
border: 0;
outline: none;
border-radius: 30px;
}
.checkbox {
margin: 30px 10px 30px 0;
}
span {
color: #777;
font-size: 12px;
bottom: 68px;
position: absolute;
}
#login {
left: 50px;
}
#register {
left: 450px;
}