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;
 | 
			
		||||
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping(path = "/")
 | 
			
		||||
@RequestMapping(path = {"/", "/home"})
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class HomePage {
 | 
			
		||||
	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>
 | 
			
		||||
                    </h5>
 | 
			
		||||
                    <h6 class="card-subtitle text-muted mb-2">
 | 
			
		||||
                        Est. Account Balance:
 | 
			
		||||
                        My Account Balance:
 | 
			
		||||
                        <span class="badge bg-secondary">
 | 
			
		||||
                    <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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@
 | 
			
		|||
        th:replace="~{layout/basic_page :: layout (title='Remove Account', content=~{::#content})}"
 | 
			
		||||
>
 | 
			
		||||
<div id="content" class="container">
 | 
			
		||||
    <h1>Remove Account</h1>
 | 
			
		||||
    <h1 class="display-4">Remove Account</h1>
 | 
			
		||||
    <p>
 | 
			
		||||
        Are you sure you want to remove this account?
 | 
			
		||||
    </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>
 | 
			
		||||
 | 
			
		||||
            <h3>Getting Started</h3>
 | 
			
		||||
            <p>
 | 
			
		||||
                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
 | 
			
		||||
                may buy and sell tradeable assets, and transfer funds to other accounts.
 | 
			
		||||
            </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>
 | 
			
		||||
		Loading…
	
		Reference in New Issue