Added request exchange functionality.
This commit is contained in:
		
							parent
							
								
									f768d62342
								
							
						
					
					
						commit
						7b5c9ddca9
					
				| 
						 | 
					@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 | 
				
			||||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
					import org.springframework.web.bind.annotation.RequestMapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Controller
 | 
					@Controller
 | 
				
			||||||
@RequestMapping(path = "/")
 | 
					@RequestMapping(path = {"/", "/home"})
 | 
				
			||||||
@RequiredArgsConstructor
 | 
					@RequiredArgsConstructor
 | 
				
			||||||
public class HomePage {
 | 
					public class HomePage {
 | 
				
			||||||
	private final AccountService accountService;
 | 
						private final AccountService accountService;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					package nl.andrewl.coyotecredit.ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import lombok.RequiredArgsConstructor;
 | 
				
			||||||
 | 
					import nl.andrewl.coyotecredit.ctl.dto.RequestExchangePayload;
 | 
				
			||||||
 | 
					import nl.andrewl.coyotecredit.dao.ExchangeRequestRepository;
 | 
				
			||||||
 | 
					import nl.andrewl.coyotecredit.model.ExchangeRequest;
 | 
				
			||||||
 | 
					import nl.andrewl.coyotecredit.model.User;
 | 
				
			||||||
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal;
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Controller;
 | 
				
			||||||
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.GetMapping;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.ModelAttribute;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.PostMapping;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.RequestMapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Controller
 | 
				
			||||||
 | 
					@RequestMapping(path = "/requestExchange")
 | 
				
			||||||
 | 
					@RequiredArgsConstructor
 | 
				
			||||||
 | 
					public class RequestExchangeController {
 | 
				
			||||||
 | 
						private final ExchangeRequestRepository exchangeRequestRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@GetMapping
 | 
				
			||||||
 | 
						public String get() {
 | 
				
			||||||
 | 
							return "exchange/request_exchange";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@PostMapping
 | 
				
			||||||
 | 
						@Transactional
 | 
				
			||||||
 | 
						public String post(@AuthenticationPrincipal User user, @ModelAttribute RequestExchangePayload payload) {
 | 
				
			||||||
 | 
							exchangeRequestRepository.save(new ExchangeRequest(
 | 
				
			||||||
 | 
									user, payload.estimatedAccountCount(), payload.organization(), payload.reason()
 | 
				
			||||||
 | 
							));
 | 
				
			||||||
 | 
							return "redirect:/";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					package nl.andrewl.coyotecredit.ctl.dto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public record RequestExchangePayload (
 | 
				
			||||||
 | 
							int estimatedAccountCount,
 | 
				
			||||||
 | 
							String organization,
 | 
				
			||||||
 | 
							String reason
 | 
				
			||||||
 | 
					) {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					package nl.andrewl.coyotecredit.dao;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewl.coyotecredit.model.ExchangeRequest;
 | 
				
			||||||
 | 
					import org.springframework.data.jpa.repository.JpaRepository;
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Repository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Repository
 | 
				
			||||||
 | 
					public interface ExchangeRequestRepository extends JpaRepository<ExchangeRequest, Long> {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					package nl.andrewl.coyotecredit.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import lombok.AccessLevel;
 | 
				
			||||||
 | 
					import lombok.Getter;
 | 
				
			||||||
 | 
					import lombok.NoArgsConstructor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.persistence.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Represents a user's request to create a new exchange.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Entity
 | 
				
			||||||
 | 
					@NoArgsConstructor(access = AccessLevel.PROTECTED)
 | 
				
			||||||
 | 
					@Getter
 | 
				
			||||||
 | 
					public class ExchangeRequest {
 | 
				
			||||||
 | 
						@Id
 | 
				
			||||||
 | 
						@GeneratedValue(strategy = GenerationType.IDENTITY)
 | 
				
			||||||
 | 
						private Long id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@ManyToOne(optional = false, fetch = FetchType.LAZY)
 | 
				
			||||||
 | 
						private User user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Column(nullable = false)
 | 
				
			||||||
 | 
						private int estimatedAccountCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Column
 | 
				
			||||||
 | 
						private String organization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Column(nullable = false)
 | 
				
			||||||
 | 
						private String reason;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ExchangeRequest(User user, int estimatedAccountCount, String organization, String reason) {
 | 
				
			||||||
 | 
							this.user = user;
 | 
				
			||||||
 | 
							this.estimatedAccountCount = estimatedAccountCount;
 | 
				
			||||||
 | 
							this.organization = organization;
 | 
				
			||||||
 | 
							this.reason = reason;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@
 | 
				
			||||||
                        <a class="colored-link" th:href="@{/exchanges/{eId}(eId=${exchange.exchange().id()})}" th:text="${exchange.exchange().name()}"></a>
 | 
					                        <a class="colored-link" th:href="@{/exchanges/{eId}(eId=${exchange.exchange().id()})}" th:text="${exchange.exchange().name()}"></a>
 | 
				
			||||||
                    </h5>
 | 
					                    </h5>
 | 
				
			||||||
                    <h6 class="card-subtitle text-muted mb-2">
 | 
					                    <h6 class="card-subtitle text-muted mb-2">
 | 
				
			||||||
                        Est. Account Balance:
 | 
					                        My Account Balance:
 | 
				
			||||||
                        <span class="badge bg-secondary">
 | 
					                        <span class="badge bg-secondary">
 | 
				
			||||||
                    <span class="font-monospace" th:text="${exchange.account().totalBalance()}"></span> 
 | 
					                    <span class="font-monospace" th:text="${exchange.account().totalBalance()}"></span> 
 | 
				
			||||||
                    <a class="colored-link" th:text="${exchange.exchange().primaryTradeable()}" th:href="@{/tradeables/{tId}(tId=${exchange.exchange().primaryTradeableId()})}"></a>
 | 
					                    <a class="colored-link" th:text="${exchange.exchange().primaryTradeable()}" th:href="@{/tradeables/{tId}(tId=${exchange.exchange().primaryTradeableId()})}"></a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
        th:replace="~{layout/basic_page :: layout (title='Remove Account', content=~{::#content})}"
 | 
					        th:replace="~{layout/basic_page :: layout (title='Remove Account', content=~{::#content})}"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
<div id="content" class="container">
 | 
					<div id="content" class="container">
 | 
				
			||||||
    <h1>Remove Account</h1>
 | 
					    <h1 class="display-4">Remove Account</h1>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
        Are you sure you want to remove this account?
 | 
					        Are you sure you want to remove this account?
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html
 | 
				
			||||||
 | 
					        lang="en"
 | 
				
			||||||
 | 
					        xmlns:th="http://www.thymeleaf.org"
 | 
				
			||||||
 | 
					        th:replace="~{layout/basic_page :: layout (title='Request Exchange', content=~{::#content})}"
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					<div id="content" class="container">
 | 
				
			||||||
 | 
					    <div class="row justify-content-center">
 | 
				
			||||||
 | 
					        <div class="col-lg-6">
 | 
				
			||||||
 | 
					            <h1 class="display-4">Request a New Exchange</h1>
 | 
				
			||||||
 | 
					            <p>
 | 
				
			||||||
 | 
					                Fill in the requested information below to submit your request
 | 
				
			||||||
 | 
					                for a new exchange.
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <form th:action="@{/requestExchange}" method="post">
 | 
				
			||||||
 | 
					                <div class="mb-3">
 | 
				
			||||||
 | 
					                    <label for="estimatedAccountCountInput" class="form-label">Estimated Number of Accounts</label>
 | 
				
			||||||
 | 
					                    <input class="form-control" type="number" name="estimatedAccountCount" id="estimatedAccountCountInput" min="1" max="1000" step="1" value="5" required/>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="mb-3">
 | 
				
			||||||
 | 
					                    <label for="organizationInput" class="form-label">Organization</label>
 | 
				
			||||||
 | 
					                    <small class="text-muted">The name of the organization that will use this exchange, if any.</small>
 | 
				
			||||||
 | 
					                    <input class="form-control" type="text" name="organization" id="organizationInput"/>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="mb-3">
 | 
				
			||||||
 | 
					                    <label for="reasonInput" class="form-label">Reason</label>
 | 
				
			||||||
 | 
					                    <small class="text-muted">Give some motivation for why you'd like to request an exchange.</small>
 | 
				
			||||||
 | 
					                    <textarea id="reasonInput" name="reason" class="form-control" rows="3" required></textarea>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <button type="submit" class="btn btn-primary">Submit</button>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -17,11 +17,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <hr>
 | 
					            <hr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <h3>Getting Started</h3>
 | 
				
			||||||
            <p>
 | 
					            <p>
 | 
				
			||||||
                You can visit the <a class="colored-link" th:href="@{/exchanges}">Exchanges</a> page
 | 
					                You can visit the <a class="colored-link" th:href="@{/exchanges}">Exchanges</a> page
 | 
				
			||||||
                to view a list of exchanges that you're participating in. Within an exchange, you
 | 
					                to view a list of exchanges that you're participating in. Within an exchange, you
 | 
				
			||||||
                may buy and sell tradeable assets, and transfer funds to other accounts.
 | 
					                may buy and sell tradeable assets, and transfer funds to other accounts.
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
 | 
					            <p>
 | 
				
			||||||
 | 
					                If you're looking to open your own exchange for your friends, colleagues, or
 | 
				
			||||||
 | 
					                students to participate in, you can submit a
 | 
				
			||||||
 | 
					                <a class="colored-link" th:href="@{/requestExchange}">request for a new exchange.</a>
 | 
				
			||||||
 | 
					                <small class="text-muted">
 | 
				
			||||||
 | 
					                    Note that exchange requests are processed manually, on a case-by-case basis, and
 | 
				
			||||||
 | 
					                    are subject to the discretion of site administrators.
 | 
				
			||||||
 | 
					                </small>
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue