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

okay now do a merge #26

Merged
merged 19 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 127 additions & 5 deletions client/src/components/home/Home.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,134 @@
import React from "react";
import React, { useState } from "react";
import styled from "styled-components";
import RecentGroup from "./RecentGroup";
import Fetch from "../common/requests/Fetch";
import Post from "../posts/Post";

// Create the post using the Post component
const createPost = (post) => {
return <Post post={post} key={post._id} isCondensed={false} />;
};

// Create a group of posts with the RecentGroup component
const createGroup = (postList, classroomName, nameColor) => {
return (
<RecentGroup
postList={postList}
classroomName={classroomName}
nameColor={nameColor}
/>
);
};

// Sorts the posts by most recent and groups them into their specific classes
const generateSections = (data) => {
let groups = [];

if (data) {
// Initialize classes object
let classes = { class: [], color: [] };

// Populate classes object with class names and colors
data.forEach((post) => {
if (!classes.class.includes(post.course_name)) {
classes.class.push(post.course_name);
classes.color.push(post.color);
}
});

// Initialize Post Grouping dictionary
let postG = {};

// Initialize empty list for each course
classes.class.forEach((className) => {
postG[className] = [];
});

// Place posts in the Post Grouping dictionary
data.forEach((post) => {
if (post.course_name in postG) {
postG[post.course_name].push(createPost(post));
}
});

// Build the class groups
for (let i = 0; i < classes.class.length; i++) {
if (!groups.includes(classes.class[i])) {
groups.push(
createGroup(
postG[classes.class[i]],
classes.class[i],
classes.color[i]
)
);
}
}
}
return groups;
};

const Home = () => {
let endpoint = "/api/home";

// Load posts from course
const { data, errors, loading } = Fetch({
type: "get",
endpoint: endpoint,
});
console.log(data);
// if (data.result) {
// var result = data.result;
// }
// if (data.posts) {
// var groups = generateSections(data.posts);
// }

let groups = generateSections(data);

return (
<div>
<h1>Home Page</h1>
<p>Maybe we can do some kind of "recent posts" feed here.</p>
</div>
<Wrapper>
<ViewWrapper>
<ScrollingDiv>
<MaxWidth>
<h1 align="center" style={{ margin: "1em" }}>
Recent Posts
</h1>
{groups}
{/* {{ groups } || <h1 align="center">{result}</h1>} */}
{/* <RecentGroup
postList={[]}
classroomName={"Default Name"}
nameColor={"#121212"}
/> */}
</MaxWidth>
</ScrollingDiv>
</ViewWrapper>
</Wrapper>
);
};

export default Home;

const Wrapper = styled.div`
display: absolute;
height: calc(100vh - 66px);
overflow-y: auto;
`;

const ViewWrapper = styled.div`
position: relative;
width: 100%;
`;

const ScrollingDiv = styled.div`
height: 100%;
width: 100%;
padding: 0 280px 0 200px;
padding-right: 280px;
`;

const MaxWidth = styled.div`
max-width: 900px;
margin: auto;
padding-bottom: 40px;
`;
47 changes: 47 additions & 0 deletions client/src/components/home/RecentGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";

const RecentGroup = ({ postList, classroomName, nameColor }) => {
return (
<Wrapper barColor={nameColor}>
<GroupWrapper>
<GroupTitle>{classroomName}</GroupTitle>
{postList}
</GroupWrapper>
</Wrapper>
);
};

RecentGroup.propTypes = {
postList: PropTypes.array,
classroomName: PropTypes.string,
nameColor: PropTypes.string,
};

export default RecentGroup;

const Wrapper = styled.div`
width: 100%;
min-height: 85px;
margin: 1em 0;
padding: 1.5em;

border-left: 4px solid ${(props) => props.barColor};
border-radius: 0.3em;
box-shadow: 0px 1px 4px 2px rgba(0, 0, 0, 0.07);
`;

const GroupWrapper = styled.div`
width: 100%;
min-height: 85px;

/* border: 1px solid black; */
`;

const GroupTitle = styled.h1`
/* color: ${(props) => props.nameColor}; */

text-align: center;
text-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25);
`;
4 changes: 3 additions & 1 deletion client/src/components/posts/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const Sidebar = ({
return (
<FlexWrapper>
<Container>
<ClassTitle>{classroomName}</ClassTitle>
<Link to={"/course/" + courseid} style={{ textDecoration: "none" }}>
<ClassTitle>{classroomName}</ClassTitle>
</Link>

<HR />
<Section>
Expand Down
2 changes: 2 additions & 0 deletions server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from resources.comments import Comments
from resources.replies import Replies
from resources.join import Join
from resources.home import Home
# Auth imports
from auth import oauth, auth_routes

Expand Down Expand Up @@ -59,6 +60,7 @@ def after_request(response):
api.add_resource(Demo, '/demo')
api.add_resource(Me, '/me')
api.add_resource(Courses, '/courses')
api.add_resource(Home, '/home')
api.add_resource(Posts, '/courses/<string:course_id>/posts')
api.add_resource(
Comments, '/posts/<string:post_id>/comments')
Expand Down
71 changes: 71 additions & 0 deletions server/resources/home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from flask import jsonify, request
from flask_restful import reqparse, Resource
from auth import current_user, permission_layer
from mongo import *
from utils.argparser_types import str2bool
from bson.json_util import dumps
from bson.objectid import ObjectId


class Home(Resource):
def get(self):

# TODO: should I add this? Would you be able to handle this format on the front end or should I change it?
if len(current_user.courses) == 0:
return []
# return {"result": "You have not yet joined or created a course.", "posts": []}, 200

course_ids = []
for course in current_user.courses:
course_ids.append(course.course_id)

# TODO: how do we query for private posts in one course but not others?

# Add all of the user's course ids to the query params from our list of course ids
queryParams = {"courseid": {"$in": course_ids}}

# Only showing private posts or posts you've created added to query params
queryParams["$or"] = [{'isPrivate': False}, {'postedby._id': {
'$in': [current_user._id, current_user.anonymousId]}}]

# Query for desired posts using query params, order them by most recent, and limit it to 20 posts
query = Post.objects.raw(queryParams).order_by(
[("createdDate", -1)]).limit(20)

# TODO: should I add this too?
count = query.count()
if count == 0:
return []
# return {"result": "There are no posts in any of your courses yet. Don't be shy, post away!", "posts": []}, 200

# result = {"result": "", "posts": [
# self.serialize(post) for post in query]}

result = [self.serialize(post) for post in query]

# Serialize and return the posts
return result, 200

def serialize(self, post):
# Get the JSON format
result = post.to_son()

# Get the list of user courses
courses = current_user.courses

# Loop through until we find the course id that matches with the course id for the post
for course in courses:
if post.courseid == course.course_id:
break

# Add the course name and color to the resulting json we'll send back to the client
result['course_name'] = course.course_name
result['color'] = course.color

# Convert datetime to a string
date = str(result['createdDate'])
result['createdDate'] = date

date = str(result['updatedDate'])
result['updatedDate'] = date
return result