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