Skip to content

Commit

Permalink
Merge pull request #24 from mpumzee/ft_add_user_list_fe
Browse files Browse the repository at this point in the history
Added user sign up view
  • Loading branch information
mpumzee authored Jan 28, 2024
2 parents 3666728 + 274f8fe commit 2985017
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 22 deletions.
3 changes: 3 additions & 0 deletions Contributors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Contributors

## This project is a result of the hard work of the following volunteers
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ChitChat is a Python-powered Social Network.

## Installation

### Backend

1. cd into backend folder
```cd backend```

Expand Down Expand Up @@ -38,6 +40,17 @@ To run this project do the following:
```python manage.py runserver```


### FrontEnd
1. cd into the frontend folder
```cd frontend```

2. Install dependencies
```npm install```

3. Run the development server
```npm run dev```



## Contributing

Expand Down
1 change: 1 addition & 0 deletions backend/accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ class CustomUserAdmin(UserAdmin):

admin.site.register(CustomUser, CustomUserAdmin)
admin.site.unregister(Group)
admin.site.register(Profile)
19 changes: 19 additions & 0 deletions backend/accounts/migrations/0003_alter_profile_follows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.4 on 2024-01-26 20:49

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("accounts", "0002_profile"),
]

operations = [
migrations.AlterField(
model_name="profile",
name="follows",
field=models.ManyToManyField(
blank=True, related_name="followers", to="accounts.profile"
),
),
]
3 changes: 3 additions & 0 deletions backend/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ class Profile(models.Model):

def __str__(self):
return f" {self.user.username} - Profile"

class Meta:
ordering = ["-pk"]
34 changes: 17 additions & 17 deletions backend/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
# lookup_field = "pk"
exclude = ["password", "groups", "user_permissions", "is_staff", "is_active"]


class FollowerSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="api:user-detail",
lookup_field="pk",
view_name="api:profile-detail", lookup_field="pk"
)
username = serializers.SerializerMethodField()

def get_username(self, obj):
return f"{obj.user.username}"

class Meta:
model = CustomUser
lookup_field = "pk"
fields = [
"username",
"email",
"pk",
"url",
]
model = Profile
fields = ["username", "url"]


class ProfileSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="api:profile-detail", lookup_field="pk"
)
user = serializers.SerializerMethodField()
follows = serializers.HyperlinkedIdentityField(
view_name="api:profile-detail", lookup_field="pk", many=True
)
followers = serializers.HyperlinkedIdentityField(
view_name="api:profile-detail", lookup_field="pk", many=True
)
follows = FollowerSerializer(many=True, read_only=True)
followers = FollowerSerializer(many=True, read_only=True)

def get_user(self, obj):
return obj.user.username
Expand Down
1 change: 1 addition & 0 deletions backend/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
path("api/users/", views.CustomUserList.as_view(), name="users"),
path("api/users/<int:pk>/", views.CustomUserDetail.as_view(), name="user-detail"),
path("api/profiles/", views.ProfileList.as_view(), name="profiles"),
path("api/signup", views.SignUpView.as_view(), name="signup-view"),
path(
"api/profiles/<int:pk>/", views.ProfileDetail.as_view(), name="profile-detail"
),
Expand Down
17 changes: 16 additions & 1 deletion backend/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ProfileList(generics.ListAPIView):

queryset = Profile.objects.all()
serializer_class = ProfileSerializer
permission_classes = [permissions.IsAuthenticated]
# permission_classes = [permissions.IsAuthenticated]


class ProfileDetail(generics.RetrieveAPIView):
Expand Down Expand Up @@ -116,3 +116,18 @@ def post(self, request, username):
{"message": f"you're no longer following {profile.user.username}"},
status=200,
)


class SignUpView(APIView):
"""
username: str
email: str
password: str
"""

def post(self, request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
9 changes: 8 additions & 1 deletion backend/chitchat/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"django.contrib.staticfiles",
# Third Party apps
"rest_framework",
"corsheaders",
# Local apps
"api",
"accounts",
Expand All @@ -51,6 +52,7 @@

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"corsheaders.middleware.CorsMiddleware", # CORS
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Expand Down Expand Up @@ -139,6 +141,11 @@
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
# "rest_framework.permissions.IsAuthenticated",
]
}


CORS_ALLOWED_ORIGINS = [
"http://localhost:5173",
]
Binary file added backend/db.sqlite3.bak
Binary file not shown.
4 changes: 4 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import Login from "./pages/auth";
import SignUpView from "./pages/Signup";
import UsersList from "./pages/UsersList";
import { Routes, Route } from "react-router-dom";

function App() {
return (
<Routes>
<Route path="/" element={<Login />} />;
<Route path="/users" element={<UsersList />} />
<Route path="/signup" element={<SignUpView />} />
</Routes>
);
}
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/components/auth/index.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { Button, Card, TextInput, Avatar } from "flowbite-react";
import { useState } from "react";

export default function Login() {
return (
const [data, setData] = useState({
email: "",
password: ""
})

const onChange = (e) => {
setData({ ...data, [e.target.id]: e.target.value })
}
return (<>
<center style={{ marginTop: "250px" }}>
<Card className="max-w-md">
<Avatar img="/user.png" rounded size="xl" />
<h3 className="text-center text-xl mb-4 mt-4">Welcome to Chit-Chat</h3>
<form className="flex flex-col gap-4">
<div>
<TextInput id="email" placeholder="Email" required type="email" />
<TextInput id="email" placeholder="Email" required type="email" onChange={onChange} />
</div>
<div>
<TextInput
Expand All @@ -23,5 +32,6 @@ export default function Login() {
</form>
</Card>
</center>
</>
);
}
59 changes: 58 additions & 1 deletion frontend/src/components/registration/index.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
import { Button, Card, TextInput, Avatar } from "flowbite-react";
import { useState } from "react";
import axios from "axios"

export default function Registration() {
return <div>Registration</div>;
const [data, setData] = useState({
email: "",
password: "",
first_name: "",
last_name: "",
username: "",
})

const onChange = (e) => {
setData({ ...data, [e.target.id]: e.target.value })
}

const onSubmit = () => {
if (data.email === "" || data.password === "" || data.first_name === "" || data.last_name === "" || data.username === "") (
alert("All fields are required")
)
axios.post("http://localhost:8000/api/signup", data).then((res) => {
alert("Successfully signed up")
}).catch((err) => {
alert("Failed to submit")
})
}

return <center style={{ marginTop: "250px" }}>
<Card className="max-w-md">
<Avatar img="/user.png" rounded size="xl" />
<h3 className="text-center text-xl mb-4 mt-4">Welcome to Chit-Chat</h3>
<form className="flex flex-col gap-4">
<div>
<TextInput id="first_name" placeholder="First Name" required type="text" onChange={onChange} />
</div>
<div>
<TextInput id="last_name" placeholder="Last Name" required type="text" onChange={onChange} />
</div>
<div>
<TextInput id="username" placeholder="Username" required type="text" onChange={onChange} />
</div>
<div>
<TextInput id="email" placeholder="Email" required type="email" onChange={onChange} />
</div>
<div>
<TextInput
id="password"
required
type="password"
placeholder="Password"
onChange={onChange}
/>
</div>

<Button onClick={onSubmit}>Register</Button>
</form>
</Card>
</center>
}
6 changes: 6 additions & 0 deletions frontend/src/pages/Signup/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Registration from "../../components/registration";


export default function SignUpView() {
return <Registration />
}
25 changes: 25 additions & 0 deletions frontend/src/pages/UsersList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { useEffect, useState } from "react";

function UsersList() {
const [users, setUsers] = useState([]);

useEffect(() => {
fetch('http://127.0.0.1:9000/api/profiles/')
.then(response => response.json())
.then(data => setUsers(data));

}, []);

return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.user}</li>
))}
</ul>
</div>
);
}

export default UsersList;

0 comments on commit 2985017

Please sign in to comment.