index and games page.
This commit is contained in:
parent
aecd4fd77a
commit
5d81f6b890
14
src/main/java/com/alterdekim/game/ThymeleafConfig.java
Normal file
14
src/main/java/com/alterdekim/game/ThymeleafConfig.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.alterdekim.game;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect;
|
||||
|
||||
@Configuration
|
||||
public class ThymeleafConfig {
|
||||
|
||||
@Bean
|
||||
public SpringSecurityDialect springSecurityDialect(){
|
||||
return new SpringSecurityDialect();
|
||||
}
|
||||
}
|
@ -33,12 +33,27 @@ public class AuthController {
|
||||
return "game";
|
||||
}
|
||||
|
||||
@GetMapping("/rules")
|
||||
public String rulesPage(Model model) {
|
||||
return "rules";
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public String loginPage(Model model) {
|
||||
model.addAttribute("title", "Login" + base_title);
|
||||
return "login";
|
||||
}
|
||||
|
||||
@GetMapping("/games")
|
||||
public String gamesPage(Model model) {
|
||||
return "games";
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public String homePage(Model model) {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/access-denied")
|
||||
public String accessDenied(Model model) {
|
||||
model.addAttribute("title", "Access denied");
|
||||
@ -63,17 +78,22 @@ public class AuthController {
|
||||
if(existingUser != null && existingUser.getUsername() != null && !existingUser.getUsername().isEmpty() ){
|
||||
result.rejectValue("username", null,
|
||||
"There is already an account registered with the same username");
|
||||
return "redirect:/signup?error=1";
|
||||
return "redirect:/signup?error=already_exists";
|
||||
}
|
||||
|
||||
if(!existingInvite.getInvite_code().equals(userDto.getInvite_code())) {
|
||||
result.rejectValue("invite_code", null, "Incorrect invite code.");
|
||||
return "redirect:/signup?error=1";
|
||||
return "redirect:/signup?error=bad_invite";
|
||||
}
|
||||
|
||||
if(!userDto.getTerms_and_conditions_accept()) {
|
||||
result.rejectValue("terms_and_conditions_accept", null, "You must accept terms and conditions");
|
||||
return "redirect:/signup?error=terms_and_conditions";
|
||||
}
|
||||
|
||||
if(result.hasErrors()) {
|
||||
model.addAttribute("user", new UserDTO());
|
||||
return "redirect:/signup?error=1";
|
||||
return "redirect:/signup?error=other";
|
||||
}
|
||||
|
||||
userService.saveUser(userDto);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.alterdekim.game.dto;
|
||||
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@ -18,6 +19,7 @@ public class UserDTO {
|
||||
private String password;
|
||||
@NotEmpty(message = "Invite code should not be empty")
|
||||
private String invite_code;
|
||||
private Boolean terms_and_conditions_accept;
|
||||
|
||||
private String lang;
|
||||
}
|
||||
|
@ -29,11 +29,12 @@ public class SpringSecurity {
|
||||
http.csrf().disable()
|
||||
.authorizeHttpRequests((authorize) ->
|
||||
authorize
|
||||
.requestMatchers("/game").permitAll()
|
||||
.requestMatchers("/games").permitAll()
|
||||
.requestMatchers("/game").hasAnyAuthority("ROLE_ADMIN")
|
||||
.requestMatchers("/games").hasAnyAuthority("ROLE_ADMIN")
|
||||
.requestMatchers("/static/**").permitAll()
|
||||
.requestMatchers("/access-denied").permitAll()
|
||||
.requestMatchers("/signup").permitAll()
|
||||
.requestMatchers("/rules").permitAll()
|
||||
.requestMatchers("/favicon.ico").permitAll()
|
||||
.requestMatchers("/signup/**").permitAll()
|
||||
.requestMatchers("/").permitAll()
|
||||
@ -42,7 +43,7 @@ public class SpringSecurity {
|
||||
.loginPage("/login")
|
||||
.loginProcessingUrl("/login")
|
||||
.failureForwardUrl("/")
|
||||
.defaultSuccessUrl("/game")
|
||||
.defaultSuccessUrl("/games")
|
||||
.permitAll()
|
||||
)
|
||||
.logout(
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.alterdekim.game.service;
|
||||
|
||||
import com.alterdekim.game.entities.Role;
|
||||
import com.alterdekim.game.entities.User;
|
||||
import com.alterdekim.game.repository.UserRepository;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public CustomUserDetailsService(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||
User user = userRepository.findByUsername(email);
|
||||
|
||||
if (user != null) {
|
||||
return new org.springframework.security.core.userdetails.User(user.getUsername(),
|
||||
user.getPassword(),
|
||||
mapRolesToAuthorities(user.getRoles()));
|
||||
}else{
|
||||
throw new UsernameNotFoundException("Invalid username or password.");
|
||||
}
|
||||
}
|
||||
|
||||
private Collection< ? extends GrantedAuthority> mapRolesToAuthorities(Collection <Role> roles) {
|
||||
return roles.stream()
|
||||
.map(role -> new SimpleGrantedAuthority(role.getName()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
16
src/main/resources/templates/access-denied.html
Normal file
16
src/main/resources/templates/access-denied.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
</head>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/navbar}"></th:block>
|
||||
|
||||
<div class="container mt-5 min-vh-100" style="max-width: 330px;">
|
||||
<h4 class="text-center">Access denied</h4>
|
||||
</div>
|
||||
|
||||
<th:block th:insert="~{fragments/footer}"></th:block>
|
||||
<th:block th:insert="~{fragments/essentials}"></th:block>
|
||||
</body>
|
||||
</html>
|
@ -1,6 +1,7 @@
|
||||
<th:block th:fragment="essentials">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
|
||||
|
@ -9,7 +9,7 @@
|
||||
All brands and trademarks on this page belong to their respective owners and are advertised.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mx-auto col-lg-6 col-md-12 mb-4 mb-md-0">
|
||||
<div class="col-lg-4 col-md-12 mb-4 mb-md-0">
|
||||
<h6 class="text-uppercase">Social</h6>
|
||||
<p>
|
||||
Follow Monopoly on social networks to stay up to date with game updates.
|
||||
|
@ -2,7 +2,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title th:text="${title} ? ${title} : 'Nosedive'"></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/static/images/favicon.ico">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500,800" rel="stylesheet">
|
||||
<link href="/static/css/style.css" rel="stylesheet">
|
||||
</th:block>
|
@ -2,30 +2,42 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-light">
|
||||
<div class="container-fluid">
|
||||
<div class="collapse navbar-collapse justify-content-center" id="navbarNav">
|
||||
<a class="navbar-brand" href="/">Nosedive</a>
|
||||
<a class="navbar-brand navbar-brand-custom" href="/">Nosedive</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-primary navbar-btn">
|
||||
<ion-icon name="game-controller-outline"></ion-icon>
|
||||
<span>Games</span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-outline-primary navbar-btn">
|
||||
<ion-icon name="people-outline"></ion-icon>
|
||||
<span>Friends</span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-outline-primary navbar-btn">
|
||||
<ion-icon name="briefcase-outline"></ion-icon>
|
||||
<span>Inventory</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<th:block sec:authorize="isAuthenticated()">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a href="/games" class="btn btn-primary navbar-btn">
|
||||
<ion-icon name="game-controller-outline"></ion-icon>
|
||||
<span>Games</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/friends" class="btn btn-outline-primary navbar-btn">
|
||||
<ion-icon name="people-outline"></ion-icon>
|
||||
<span>Friends</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/inventory" class="btn btn-outline-primary navbar-btn">
|
||||
<ion-icon name="briefcase-outline"></ion-icon>
|
||||
<span>Inventory</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</th:block>
|
||||
<th:block sec:authorize="isAnonymous()">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a href="/login" class="btn btn-primary navbar-btn">
|
||||
<ion-icon name="log-in-outline"></ion-icon>
|
||||
<span>Login</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</th:block>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
121
src/main/resources/templates/games.html
Normal file
121
src/main/resources/templates/games.html
Normal file
@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
<style>
|
||||
.grid {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(12,1fr);
|
||||
grid-column-gap: 25px;
|
||||
}
|
||||
|
||||
.g-col-4 {
|
||||
grid-column-end: span 4;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.g-col-8 {
|
||||
grid-column-end: span 8;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
border-bottom: 2px solid rgba(0,0,0,.1);
|
||||
border-radius: 5px;
|
||||
padding-top: .1px;
|
||||
padding-bottom: .1px;
|
||||
width: 100%;
|
||||
min-height: 1px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 1000px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.block-content {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.market {
|
||||
height: 160px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.transparent-override {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.text-glowing {
|
||||
color: rgba(55, 188, 157, 1) !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/navbar}"></th:block>
|
||||
<div class="container">
|
||||
<div class="grid mt-5">
|
||||
<div class="g-col-4">
|
||||
<div class="block">
|
||||
<div class="title">Achievements</div>
|
||||
<div class="block-content">
|
||||
<div class="spinner-grow text-glowing" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block" style="margin-top: 15px;">
|
||||
<div class="title">Friends</div>
|
||||
<div class="block-content">
|
||||
<div class="spinner-grow text-glowing" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-col-8">
|
||||
<div class="block transparent-override">
|
||||
<div class="market">
|
||||
<div class="spinner-grow text-glowing" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block" style="margin-top: 15px;">
|
||||
<div class="title">Chat</div>
|
||||
<div class="block-content" style="height: 280px; align-items: center;">
|
||||
<div class="spinner-grow text-glowing" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block" style="margin-top: 15px;">
|
||||
<div class="title">Waiting list</div>
|
||||
<div class="block-content">
|
||||
<div class="spinner-grow text-glowing" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/essentials}"></th:block>
|
||||
</body>
|
||||
</html>
|
168
src/main/resources/templates/index.html
Normal file
168
src/main/resources/templates/index.html
Normal file
@ -0,0 +1,168 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
<style>
|
||||
.navbar-brand-custom {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.navbar-brand-custom:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #37bc9d;
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
border-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: rgba(255,255,255,.85);
|
||||
color: #37bc9d;
|
||||
border-color: rgba(255,255,255,.85);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #ffffff;
|
||||
border-color: #ffffff;
|
||||
color: #37bc9d;
|
||||
}
|
||||
|
||||
.btn-outline-primary:hover {
|
||||
background-color: rgba(255, 255, 255,0.25);
|
||||
border-color: rgba(255, 255, 255,0.25);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font: 700 3.5em Montserrat;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.page-title-small {
|
||||
margin-top: .7em;
|
||||
font: 500 1.32em/1.4em Montserrat;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.main-billboard {
|
||||
background-color: #37bc9d;
|
||||
height: 700px;
|
||||
text-align: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.main-button {
|
||||
color: #5b5d67;
|
||||
background-color: #fff;
|
||||
border-color: #fff;
|
||||
font: 600 1.5rem Montserrat;
|
||||
padding: 0 0.9em;
|
||||
height: 2.1em;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.main-button:hover {
|
||||
color: #5b5d67;
|
||||
background-color: rgba(255, 255, 255, 0.85);
|
||||
border-color: rgba(255, 255, 255, 0.85);
|
||||
font: 600 1.5rem Montserrat;
|
||||
padding: 0 0.9em;
|
||||
height: 2.1em;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.page-main-button {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.page-title-second {
|
||||
margin-top: 1.25em;
|
||||
margin-right: 0px;
|
||||
margin-bottom: 1.25em;
|
||||
margin-left: 0px;
|
||||
font: 700 3.25em Montserrat;
|
||||
color: #26272b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.billboard-img {
|
||||
box-shadow: 0 0 100px rgba(0,0,0,.33);
|
||||
width: 900px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.billboard-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 0 0 .4em;
|
||||
font: 700 2em Montserrat;
|
||||
}
|
||||
|
||||
.col_text {
|
||||
font-size: 1.1em;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/navbar}"></th:block>
|
||||
<div class="container-fluid main-billboard">
|
||||
<div class="page-title">Welcome to Nosedive.</div>
|
||||
<div class="page-title-small">Reinvented legendary game online.</div>
|
||||
<div class="page-main-button"><a class="btn btn-primary main-button" href="/games">Start game</a></div>
|
||||
<div class="billboard-container"><img src="//m1.dogecdn.wtf/website/index/screenshot.png" class="rounded billboard-img"></div> <!-- 900 -->
|
||||
<div class="page-title-second">Why will you like <span style="background: linear-gradient(90deg, hsl(166, 55%, 30%) 0%, rgba(55,188,157,1) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">Nosedive</span>?</div>
|
||||
<div class="container text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>That's free!</h4>
|
||||
<div class="col_text">Just sign up and start a game — no payments or subscriptions.</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>New gameplay</h4>
|
||||
<div class="col_text">We've breathed new life into a beloved classic! Get ready for a familiar favorite with a strategic twist that turns the fun factor up to eleven.</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>PVP-mode</h4>
|
||||
<div class="col_text">Unleash your skills in PVP mode and witness your rank soar with every triumphant victory. The ladder awaits.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 50px;">
|
||||
<div class="col">
|
||||
<h4>New friends</h4>
|
||||
<div class="col_text">Discover a vibrant social sphere within the game! Forge connections with like-minded players who share your passions and thirst for victory.</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Hoarding</h4>
|
||||
<div class="col_text">We have dozens of items, some of them very rare. You can earn them, by winning the games. We're all a little hoarders, right?</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Play anywhere</h4>
|
||||
<div class="col_text">You can play on any device that has a browser.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid" style="min-height: 750px; background-color: #f4f4f5">
|
||||
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/footer}"></th:block>
|
||||
<th:block th:insert="~{fragments/essentials}"></th:block>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$(".navbar").removeClass("navbar-light");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
</head>
|
||||
@ -8,11 +8,11 @@
|
||||
|
||||
<div class="container mt-5 min-vh-100" style="max-width: 330px;">
|
||||
<h4 class="text-center">Login</h4>
|
||||
<th:block th:if="${param.error}">
|
||||
<div class="alert alert-danger" role="alert" th:text="#{login_error}"></div>
|
||||
<th:block th:switch="${#strings.toString(param.error)}">
|
||||
<div th:case="'bad_credentials'" class="alert alert-danger" role="alert">Wrong nickname or(and) password</div>
|
||||
</th:block>
|
||||
<th:block th:if="${error}">
|
||||
<div class="alert alert-danger" role="alert" th:text="#{login_error}"></div>
|
||||
<div class="alert alert-danger" role="alert" th:text="${error}"></div>
|
||||
</th:block>
|
||||
<form method="post" th:action="@{/login}">
|
||||
<div class="mb-3">
|
||||
|
56
src/main/resources/templates/rules.html
Normal file
56
src/main/resources/templates/rules.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
</head>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/navbar}"></th:block>
|
||||
|
||||
<div class="container mt-5 min-vh-100" style="max-width: 660px;">
|
||||
<h4>Terms of service</h4>
|
||||
<p><em>Last updated: 02/14/2024</em></p>
|
||||
<h5>1. Introduction:</h5>
|
||||
|
||||
<p>Welcome to Nosedive! This document outlines the terms and conditions (the "Terms") governing your use of the game and its components. Please read these Terms carefully before playing. By playing the game, you agree to be bound by these Terms.</p>
|
||||
|
||||
<h5>2. Ownership and Intellectual Property:</h5>
|
||||
|
||||
<p>Nosedive is owned and operated by alterdekim. All intellectual property rights, including copyrights, trademarks, and patents, associated with the game belong to alterdekim.</p>
|
||||
|
||||
<h5>3. Use of the Game:</h5>
|
||||
|
||||
<p>This game is intended for private, non-commercial use only. You may not sell, reproduce, distribute, or modify the game or its components without our prior written consent.</p>
|
||||
|
||||
<h5>4. Disclaimer of Warranties:</h5>
|
||||
|
||||
<p>The game is provided <strong>"as is"</strong> and without any warranties, express or implied. We do not guarantee that the game will be free of errors or bugs.</p>
|
||||
|
||||
<h5>5. Limitation of Liability:</h5>
|
||||
|
||||
<p>We shall not be liable for any damages arising from your use of the game, including but not limited to, direct, indirect, incidental, consequential, or punitive damages.</p>
|
||||
|
||||
<h5>6. Age Restriction:</h5>
|
||||
|
||||
<p>This game is intended for players aged <strong>18</strong> and above. Parental supervision is recommended for younger players.</p>
|
||||
|
||||
<h5>7. Changes to the Terms:</h5>
|
||||
|
||||
<p>We reserve the right to modify these Terms at <strong>any time</strong>. Your continued use of the game following any changes constitutes your acceptance of the revised Terms.</p>
|
||||
|
||||
<h5>8. Governing Law:</h5>
|
||||
|
||||
<p>These Terms shall be governed by and construed in accordance with the laws of the United States of America.</p>
|
||||
|
||||
<h5>9. Dispute Resolution:</h5>
|
||||
|
||||
<p>Any dispute arising out of or relating to these Terms shall be submitted to binding arbitration in accordance with the rules of the American Arbitration Association. The arbitration shall be held in Texas, and the decision of the arbitrator shall be final and binding.</p>
|
||||
|
||||
<h5>10. Contact Us:</h5>
|
||||
|
||||
<p>If you have any questions about these Terms, please contact us at alterwain@protonmail.com</p>
|
||||
</div>
|
||||
|
||||
<th:block th:insert="~{fragments/footer}"></th:block>
|
||||
<th:block th:insert="~{fragments/essentials}"></th:block>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/head}"></th:block>
|
||||
</head>
|
||||
@ -8,11 +8,14 @@
|
||||
|
||||
<div class="container mt-5 min-vh-100" style="max-width: 330px;">
|
||||
<h4 class="text-center">Sign up</h4>
|
||||
<th:block th:if="${param.error}">
|
||||
<div class="alert alert-danger" role="alert" th:text="#{login_error}"></div>
|
||||
<th:block th:switch="${#strings.toString(param.error)}">
|
||||
<div th:case="'terms_and_conditions'" class="alert alert-danger" role="alert">You must accept terms and conditions</div>
|
||||
<div th:case="'bad_invite'" class="alert alert-danger" role="alert">Bad invite code</div>
|
||||
<div th:case="'already_exists'" class="alert alert-danger" role="alert">User with that nickname already exists</div>
|
||||
<div th:case="'other'" class="alert alert-danger" role="alert">Internal server error</div>
|
||||
</th:block>
|
||||
<th:block th:if="${error}">
|
||||
<div class="alert alert-danger" role="alert" th:text="#{login_error}"></div>
|
||||
<div class="alert alert-danger" role="alert" th:text="${error}"></div>
|
||||
</th:block>
|
||||
<form method="post" th:action="@{/signup}" th:object="${user}">
|
||||
<div class="mb-3">
|
||||
@ -20,7 +23,7 @@
|
||||
<input type="text" name="username" class="form-control" id="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Password must have at least 7 symbols, include letters, digits, any of special symbols (#$%:;~|&^!_\/-+*)"><ion-icon name="key-outline"></ion-icon> Password</label>
|
||||
<label for="password" class="form-label"><ion-icon name="key-outline"></ion-icon> Password</label>
|
||||
<input type="password" name="password" class="form-control" id="password">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
@ -29,13 +32,15 @@
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
|
||||
<label class="form-check-label" for="flexCheckDefault">
|
||||
I have read the terms and conditions
|
||||
<input class="form-check-input" type="checkbox" value="" name="terms_and_conditions_accept" th:field="${user.terms_and_conditions_accept}" id="terms_and_conditions_accept">
|
||||
<label class="form-check-label" for="terms_and_conditions_accept">
|
||||
I have read the <a href="/rules">terms and conditions</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Sign up</button>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary">Sign up</button>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<p>Already have an account? <a href="/login">Login</a></p>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user