Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adam make post page #51

Merged
merged 20 commits into from
Apr 18, 2024
75 changes: 53 additions & 22 deletions backend/src/controllers/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"net/http"
"strconv"

"fmt"

"backend/src/models"
"backend/src/services"
"backend/src/types"

"github.com/gin-gonic/gin"
)
Expand Down Expand Up @@ -115,36 +118,64 @@ func (pc *PostController) GetPostsFromSearch(c *gin.Context) {
c.JSON(http.StatusOK, posts)
}

// CreatePost godoc
//
// @Summary Creates a post
// @Description Creates a post
// @ID create-post
// @Tags post
// @Accept json
// @Produce json
// @Param first_name body string true "First name of the post"
// @Param last_name body string true "Last name of the post"
// @Param postname body string true "Postname of the post"
// @Param email body string true "Email of the post"
// @Param password body string true "Password of the post"
// @Success 201 {object} models.Post
// @Failure 400 {string} string "Failed to create post"
// @Router /api/posts/ [post]
func (pc *PostController) CreatePost(c *gin.Context) {
var post models.Post
if err := c.ShouldBindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
// CreateTradePost godoc
func (pc *PostController) CreateTradePost(c *gin.Context) {
var req types.CreateTradePostRequest
if err := c.BindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}

createdPost, err := pc.postService.CreatePost(&post)
userId := c.Param("user_id")

fmt.Println(req.Title, req.Description)

tradePost, err := pc.postService.CreateTradePost(userId, req.PercentData, req.TickerSymbol, req.Title, req.Description)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create post"})
return
}

c.JSON(http.StatusCreated, tradePost)
}

// CreatePortfolioPost godoc
func (pc *PostController) CreatePortfolioPost(c *gin.Context) {
var req types.CreatePortfolioPostRequest
if err := c.BindJSON(&req); err != nil {
fmt.Println(err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}

userId := c.Param("user_id")

portfolioPost, err := pc.postService.CreatePortfolioPost(userId, req.PercentData, req.SummaryType)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create post"})
return
}

c.JSON(http.StatusCreated, portfolioPost)
}

// CreateTextPost godoc
func (pc *PostController) CreateTextPost(c *gin.Context) {
var req types.CreateTextPostRequest
if err := c.BindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}

userId := c.Param("user_id")

textPost, err := pc.postService.CreateTextPost(userId, req.Title, req.Description)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create post"})
return
}

c.JSON(http.StatusCreated, createdPost)
c.JSON(http.StatusCreated, textPost)
}

// GetPostById godoc
Expand Down
4 changes: 2 additions & 2 deletions backend/src/db/migrations/7_POST_V1.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ CREATE TYPE post_type_enum AS ENUM (
--Create post table
CREATE TABLE IF NOT EXISTS posts (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_id VARCHAR(255) REFERENCES users(id) ON DELETE CASCADE,
post_type post_type_enum NOT NULL,
num_data FLOAT NOT NULL,
Expand Down
4 changes: 3 additions & 1 deletion backend/src/routes/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ func SetupPostRoutes(router *gin.Engine, db *gorm.DB) {
postRoutes.GET("/user-posts/:user_id", postController.GetPostsByUserId)
postRoutes.GET("/followed-posts/:user_id", postController.GetPostsFromFollowedUsers)
postRoutes.GET("/search-posts", postController.GetPostsFromSearch)
postRoutes.POST("", postController.CreatePost)
postRoutes.POST("/create-trade-post/:user_id", postController.CreateTradePost)
postRoutes.POST("/create-portfolio-post/:user_id", postController.CreatePortfolioPost)
postRoutes.POST("/create-text-post/:user_id", postController.CreateTextPost)
postRoutes.GET("/:id", postController.GetPostById)
postRoutes.PUT("/:id", postController.UpdatePostById)
postRoutes.DELETE("/:id", postController.DeletePostById)
Expand Down
48 changes: 45 additions & 3 deletions backend/src/services/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,53 @@ func (ps *PostService) GetPostsFromSearch(postContentSearchTerm string) ([]model
return posts, nil
}

func (ps *PostService) CreatePost(post *models.Post) (*models.Post, error) {
if err := ps.DB.Create(post).Error; err != nil {
func (ps *PostService) CreateTradePost(userId string, percentData float64, tickerSymbol string, title string, description string) (*models.Post, error) {
tradePost := &models.Post{
UserID: userId,
NumData: percentData,
PostType: models.RECENT_TRADE,
TickerSymbol: tickerSymbol,
Title: title,
Comment: description,
}

if err := ps.DB.Create(tradePost).Error; err != nil {
return nil, err
}
return post, nil

return tradePost, nil
}

func (ps *PostService) CreatePortfolioPost(userId string, percentData float64, summaryType string) (*models.Post, error) {
portfolioPost := &models.Post{
UserID: userId,
NumData: percentData,
PostType: models.ONE_MONTH_SUMMARY,
Title: "Portfolio Summary",
Comment: summaryType,
}

if err := ps.DB.Create(portfolioPost).Error; err != nil {
return nil, err
}

return portfolioPost, nil
}

func (ps *PostService) CreateTextPost(userId string, title string, description string) (*models.Post, error) {
textPost := &models.Post{
UserID: userId,
NumData: 0,
PostType: models.SHARE_COMMENT,
Title: title,
Comment: description,
}

if err := ps.DB.Create(textPost).Error; err != nil {
return nil, err
}

return textPost, nil
}

func (ps *PostService) GetPostById(id uint) (*models.Post, error) {
Expand Down
17 changes: 17 additions & 0 deletions backend/src/types/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,20 @@ type ClerkWebhookEvent struct {
Object string `json:"object"`
Type string `json:"type"`
}

type CreateTradePostRequest struct {
PercentData float64 `json:"percent_data" binding:"required"`
TickerSymbol string `json:"ticker_symbol" binding:"required"`
Title string `json:"title" binding:"required"`
Description string `json:"description" binding:"required"`
}

type CreatePortfolioPostRequest struct {
PercentData float64 `json:"percent_data" binding:"required"`
SummaryType string `json:"summary_type" binding:"required"`
}

type CreateTextPostRequest struct {
Title string `json:"title" binding:"required"`
Description string `json:"description" binding:"required"`
}
2 changes: 2 additions & 0 deletions frontend/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import onboardingReducer from './reducers/onboarding/onboardingReducer';
import makePostReducer from './reducers/makePost/makePostReducer';
import LayoutWrapper from './components/LayoutWrapper';
import { ClerkProvider } from '@clerk/clerk-expo';
//import 'react-native-gesture-handler';
Expand All @@ -10,6 +11,7 @@ import * as SecureStore from 'expo-secure-store';
const store = configureStore({
reducer: {
onboarding: onboardingReducer,
makePost: makePostReducer,
},
});

Expand Down
5 changes: 4 additions & 1 deletion frontend/components/LayoutWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import BottomNavBar from '../router/BottomNavBar';
import AuthNavigator from '../router/AuthNavigation';
import { configureStore } from '@reduxjs/toolkit';
import onboardingReducer from '../reducers/onboarding/onboardingReducer';
import makePostReducer from '../reducers/makePost/makePostReducer';
import { useSelector } from 'react-redux';
import MakePostNavigator from '../router/MakePostNavigation';

const store = configureStore({
reducer: {
onboarding: onboardingReducer,
makePost: makePostReducer,
},
});

Expand All @@ -28,7 +31,7 @@ export default function LayoutWrapper() {
{
onboarding: <AuthNavigator/>,
normal: <BottomNavBar/>,
makingPost: (null),
makingPost: <MakePostNavigator/>,
}[onboarding.isOnboarding]
}
{/* {session?.user !== undefined && !onboarding.isOnboarding ? (
Expand Down
Loading
Loading