From 0390c1c6e8f90d91136ad35f84aea2768a7e7a45 Mon Sep 17 00:00:00 2001 From: Kirubel Tadesse Date: Sun, 3 Sep 2023 08:30:07 +0100 Subject: [PATCH 1/2] fix #79 add formating for core and correct ui formating --- .devcontainer.json | 71 +++++++------- .gitignore | 40 +++++++- .prettierignore | 7 -- README.md | 6 ++ api/apps.py | 4 +- api/serializers.py | 24 ++++- api/tests.py | 44 +++++---- api/urls.py | 11 +-- api/views.py | 9 +- backend/admin.py | 17 ++-- backend/apps.py | 4 +- backend/migrations/0001_initial.py | 84 +++++++++++++---- backend/migrations/0002_rootuser_student.py | 44 +++++++++ backend/models.py | 39 ++++---- backend/tests/test_models.py | 76 +++++++++------ backend/urls.py | 2 +- core/asgi.py | 2 +- core/settings.py | 99 ++++++++++---------- core/urls.py | 32 ++++--- core/wsgi.py | 2 +- frontend/.devcontainer.json | 17 ++-- frontend/{.pretterignore => .prettierignore} | 3 +- frontend/.vscode/.prettierrc | 11 ++- frontend/.vscode/launch.json | 52 +++++----- frontend/.vscode/settings.json | 13 ++- frontend/.vscode/tasks.json | 28 +++--- frontend/install-dev-packages.sh | 3 +- frontend/npm-shrinkwrap.json | 8 +- frontend/src/App.test.tsx | 20 ++-- frontend/src/App.tsx | 9 +- frontend/src/Calendar.test.tsx | 16 ++-- frontend/src/Calendar.tsx | 61 ++++++------ frontend/src/SignIn.test.tsx | 22 ++--- frontend/src/SignIn.tsx | 64 +++++++------ frontend/src/components/Events.tsx | 4 +- frontend/src/components/EventsLoading.tsx | 4 +- frontend/src/components/Footer.tsx | 8 +- frontend/src/components/Header.tsx | 33 +++---- frontend/src/index.tsx | 19 ++-- frontend/tsconfig.json | 20 +++- manage.py | 4 +- requirements-dev.txt | 3 +- 42 files changed, 619 insertions(+), 420 deletions(-) delete mode 100644 .prettierignore create mode 100644 backend/migrations/0002_rootuser_student.py rename frontend/{.pretterignore => .prettierignore} (95%) diff --git a/.devcontainer.json b/.devcontainer.json index fb3a820b..d9f4e565 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -1,43 +1,44 @@ { - "name": "Existing Docker Compose (Extend)", + "name": "Existing Docker Compose (Extend)", - "dockerComposeFile": ["docker-compose.yml"], + "dockerComposeFile": ["docker-compose.yml"], - "service": "svc", + "service": "svc", - "workspaceFolder": "/workspace", + "workspaceFolder": "/workspace", - // Set *default* container specific settings.json values on container create. - "settings": { - "_workbench.uiExtensions": ["peterjausovec.vscode-docker"], - "python.jediEnabled": false, - "python.testing.pytestEnabled": true, - "pythonTestExplorer.testFramework": "pytest", - "python.testing.autoTestDiscoverOnSaveEnabled": true, - "python.pythonPath": "/usr/local/bin/python3", - "python.testing.pytestPath": "/usr/local/bin/pytest", - "editor.formatOnSave": false, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.fontFamily": "Cascadia Code, Fira Code", - "[markdown]": { - "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" + // Set *default* container specific settings.json values on container create. + "settings": { + "python.formatting.provider": "black", + "_workbench.uiExtensions": ["peterjausovec.vscode-docker"], + "python.jediEnabled": false, + "python.testing.pytestEnabled": true, + "pythonTestExplorer.testFramework": "pytest", + "python.testing.autoTestDiscoverOnSaveEnabled": true, + "python.pythonPath": "/usr/local/bin/python3", + "python.testing.pytestPath": "/usr/local/bin/pytest", + "editor.formatOnSave": false, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.fontFamily": "Cascadia Code, Fira Code", + "[markdown]": { + "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" + }, + "[python]": { + "editor.defaultFormatter": "ms-python.python" + }, + "grammarly.files.include": ["**/*.md", "**/*.txt"] }, - "[python]": { - "editor.defaultFormatter": "ms-python.python" - }, - "grammarly.files.include": ["**/*.md", "**/*.txt"] - }, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "github.copilot", - "eamodio.gitlens", - "shardulm94.trailing-spaces", - "esbenp.prettier-vscode", - "ms-python.python", - "gruntfuggly.todo-tree", - "cweijan.vscode-database-client2", - "littlefoxteam.vscode-python-test-adapter", - "ms-azuretools.vscode-docker" - ] + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "github.copilot", + "eamodio.gitlens", + "shardulm94.trailing-spaces", + "esbenp.prettier-vscode", + "ms-python.python", + "gruntfuggly.todo-tree", + "cweijan.vscode-database-client2", + "littlefoxteam.vscode-python-test-adapter", + "ms-azuretools.vscode-docker" + ] } diff --git a/.gitignore b/.gitignore index 0c9ca35d..14de25a0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,47 @@ *.pyc .DS_Store __pycache__ -.coverage* */htmlcov/* /data env env/* + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Sphinx documentation +docs/_build/ + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 6d9b99ef..00000000 --- a/.prettierignore +++ /dev/null @@ -1,7 +0,0 @@ -*/node_modules/* -package-lock.json -package.json -README.md -*.yml -*/Dockerfile -htmlcov/* diff --git a/README.md b/README.md index 19750373..72b65b6b 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,12 @@ To run the test you can just use the `pytest` package pytest ``` +Code formating + +```bash +python -m black ... +``` + ---
diff --git a/api/apps.py b/api/apps.py index 66656fd2..878e7d54 100644 --- a/api/apps.py +++ b/api/apps.py @@ -2,5 +2,5 @@ class ApiConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'api' + default_auto_field = "django.db.models.BigAutoField" + name = "api" diff --git a/api/serializers.py b/api/serializers.py index f4924230..15a88534 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -2,24 +2,38 @@ from rest_framework import serializers from backend.models import Event, Mainuser, Student, Mentor + class EventSerializer(serializers.ModelSerializer): class Meta: model = Event - fields = ('id', 'title', 'content', 'student', 'mentor', 'start_date', 'end_date', 'status') + fields = ( + "id", + "title", + "content", + "student", + "mentor", + "start_date", + "end_date", + "status", + ) + # the student class + class StudentSerializer(serializers.ModelSerializer): class Meta: - model = Mainuser - fields = ('__all__') + model = Mainuser + fields = "__all__" + class MainSerializer(serializers.ModelSerializer): class Meta: model = Student - fields = ('__all__') + fields = "__all__" + class MentorSerializer(serializers.ModelSerializer): class Meta: model = Mentor - fields = ('__all__') + fields = "__all__" diff --git a/api/tests.py b/api/tests.py index aa3a2b04..fe538fed 100644 --- a/api/tests.py +++ b/api/tests.py @@ -5,39 +5,37 @@ from django.contrib.auth.models import User from django.utils import timezone -class TestEvent(APITestCase): +class TestEvent(APITestCase): # test if the url is working def test_view_events(self): - url = reverse('api:list') - response = self.client.get(url, format='json') + url = reverse("api:list") + response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) - # test if the data is correct inserted + # test if the data is correct inserted def create_event(self): - - self.test_category = Category.objects.create(name='django') + self.test_category = Category.objects.create(name="django") self.studentUser = User.objects.create_user( - username='test_user1', password='123456789') + username="test_user1", password="123456789" + ) self.mentorUser = User.objects.create_user( - username='test_user2', password='123456789') - + username="test_user2", password="123456789" + ) + data = { - 'category_id': 1, - 'title': 'Event Title', - 'content': 'Event Content', - 'slug': 'event-title', - 'student': self.studentUser, - 'mentor': self.mentorUser, - 'start_date': timezone.now(), - 'end_date': timezone.now(), - 'status': 'published' + "category_id": 1, + "title": "Event Title", + "content": "Event Content", + "slug": "event-title", + "student": self.studentUser, + "mentor": self.mentorUser, + "start_date": timezone.now(), + "end_date": timezone.now(), + "status": "published", } - url = reverse('api:list') - response = self.client.post(url, data, format='json') + url = reverse("api:list") + response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - - diff --git a/api/urls.py b/api/urls.py index 44dbc7e9..d9dfe2bb 100644 --- a/api/urls.py +++ b/api/urls.py @@ -1,11 +1,10 @@ -from django.urls import path +from django.urls import path from .views import EventDetail, EventList, MainList -app_name = 'api' +app_name = "api" urlpatterns = [ - path('/', EventDetail.as_view(), name='detail'), - path('', EventList.as_view(), name='list'), - path('mainlist/', MainList.as_view(), name='detail'), - + path("/", EventDetail.as_view(), name="detail"), + path("", EventList.as_view(), name="list"), + path("mainlist/", MainList.as_view(), name="detail"), ] diff --git a/api/views.py b/api/views.py index b86f2a25..caac9a44 100644 --- a/api/views.py +++ b/api/views.py @@ -1,16 +1,23 @@ from rest_framework import generics from backend.models import Event, Mainuser -from .serializers import EventSerializer, MentorSerializer, MainSerializer, StudentSerializer +from .serializers import ( + EventSerializer, + MentorSerializer, + MainSerializer, + StudentSerializer, +) class EventList(generics.ListCreateAPIView): queryset = Event.eventobjects.all() serializer_class = EventSerializer + class EventDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Event.objects.all() serializer_class = EventSerializer + class MainList(generics.ListCreateAPIView): queryset = Mainuser.objects.all() serializer_class = MainSerializer diff --git a/backend/admin.py b/backend/admin.py index 423bd37a..6fcea609 100644 --- a/backend/admin.py +++ b/backend/admin.py @@ -1,15 +1,17 @@ from django.contrib import admin from . import models + @admin.register(models.Event) class EventAdmin(admin.ModelAdmin): - list_display = ('title', 'student', 'mentor', 'start_date', 'end_date', 'status') - list_filter = ('status', 'date_posted', 'start_date', 'end_date') - search_fields = ('title', 'content') - prepopulated_fields = {'slug': ('title',)} - raw_id_fields = ('student', 'mentor') - date_hierarchy = 'start_date' - ordering = ('status', 'start_date') + list_display = ("title", "student", "mentor", "start_date", "end_date", "status") + list_filter = ("status", "date_posted", "start_date", "end_date") + search_fields = ("title", "content") + prepopulated_fields = {"slug": ("title",)} + raw_id_fields = ("student", "mentor") + date_hierarchy = "start_date" + ordering = ("status", "start_date") + admin.site.register(models.Category) # Register your models here. @@ -17,4 +19,3 @@ class EventAdmin(admin.ModelAdmin): admin.site.register(models.Mainuser) admin.site.register(models.Student) - diff --git a/backend/apps.py b/backend/apps.py index 6a3779f0..f3a9df4b 100644 --- a/backend/apps.py +++ b/backend/apps.py @@ -2,5 +2,5 @@ class BackendConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'backend' + default_auto_field = "django.db.models.BigAutoField" + name = "backend" diff --git a/backend/migrations/0001_initial.py b/backend/migrations/0001_initial.py index 3ad6af4c..8c35e2d9 100644 --- a/backend/migrations/0001_initial.py +++ b/backend/migrations/0001_initial.py @@ -7,7 +7,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [ @@ -16,29 +15,80 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Category', + name="Category", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=100)), ], ), migrations.CreateModel( - name='Event', + name="Event", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=100)), - ('content', models.TextField()), - ('slug', models.SlugField(max_length=250, unique_for_date='published')), - ('date_posted', models.DateTimeField(default=django.utils.timezone.now)), - ('start_date', models.DateTimeField(default=django.utils.timezone.now)), - ('end_date', models.DateTimeField(default=django.utils.timezone.now)), - ('status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending'), ('published', 'Published')], default='published', max_length=10)), - ('category', models.ForeignKey(default=1, on_delete=django.db.models.deletion.PROTECT, to='backend.category')), - ('mentor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mentor', to=settings.AUTH_USER_MODEL)), - ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student', to=settings.AUTH_USER_MODEL)), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=100)), + ("content", models.TextField()), + ("slug", models.SlugField(max_length=250, unique_for_date="published")), + ( + "date_posted", + models.DateTimeField(default=django.utils.timezone.now), + ), + ("start_date", models.DateTimeField(default=django.utils.timezone.now)), + ("end_date", models.DateTimeField(default=django.utils.timezone.now)), + ( + "status", + models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending"), + ("published", "Published"), + ], + default="published", + max_length=10, + ), + ), + ( + "category", + models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.PROTECT, + to="backend.category", + ), + ), + ( + "mentor", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="mentor", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "student", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="student", + to=settings.AUTH_USER_MODEL, + ), + ), ], options={ - 'ordering': ('-date_posted',), + "ordering": ("-date_posted",), }, ), ] diff --git a/backend/migrations/0002_rootuser_student.py b/backend/migrations/0002_rootuser_student.py new file mode 100644 index 00000000..3232dc53 --- /dev/null +++ b/backend/migrations/0002_rootuser_student.py @@ -0,0 +1,44 @@ +# Generated by Django 4.1.2 on 2023-08-15 23:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("backend", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Rootuser", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name="Student", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("first_name", models.CharField(max_length=100)), + ("last_name", models.CharField(max_length=100)), + ("email", models.EmailField(max_length=254, unique=True)), + ], + ), + ] diff --git a/backend/models.py b/backend/models.py index 8162e245..ad65b025 100644 --- a/backend/models.py +++ b/backend/models.py @@ -20,30 +20,33 @@ # is_superuser = models.BooleanField(default=False) # name = models.CharField(max_length=100, blank=False, null=True) # phone = models.CharField(max_length=20, blank=True, null=True) + + class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name -class Mainuser(models.Model): +class Mainuser(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) - username = models.CharField(max_length=200,unique=True) + username = models.CharField(max_length=200, unique=True) password = models.CharField(max_length=250) email = models.EmailField(unique=True) jnumber = models.IntegerField() role = models.CharField(max_length=100) + class Student(Mainuser): - student_id = models.AutoField(primary_key=True) class Mentor(Mainuser): - mentor_id = models.AutoField(primary_key=True) + + # # create a model with two different user # class Mentor(models.Model): # user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='mentor') @@ -55,38 +58,38 @@ class Mentor(Mainuser): # user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='student') # category = models.ManyToManyField(Category) # def __str__(self): - + # return self.user.username + # Create Event model with title, content, date_posted, student, mentor, start_date, end_date, category, status class Event(models.Model): - class EventObjects(models.Manager): def get_queryset(self): - return super().get_queryset().filter(status='published') + return super().get_queryset().filter(status="published") options = ( - ('draft', 'Draft'), - ('pending', 'Pending'), - ('published', 'Published'), + ("draft", "Draft"), + ("pending", "Pending"), + ("published", "Published"), ) - category = models.ForeignKey( - Category, on_delete=models.PROTECT, default=1) + category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1) title = models.CharField(max_length=100) content = models.TextField() - slug = models.SlugField(max_length=250, unique_for_date='published') - student = models.ForeignKey(User, on_delete=models.CASCADE, related_name='student') - mentor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='mentor') + slug = models.SlugField(max_length=250, unique_for_date="published") + student = models.ForeignKey(User, on_delete=models.CASCADE, related_name="student") + mentor = models.ForeignKey(User, on_delete=models.CASCADE, related_name="mentor") date_posted = models.DateTimeField(default=timezone.now) start_date = models.DateTimeField(default=timezone.now) end_date = models.DateTimeField(default=timezone.now) - status = models.CharField(max_length=10, choices=options, default='published') + status = models.CharField(max_length=10, choices=options, default="published") objects = models.Manager() # The default manager. - eventobjects = EventObjects() # custom manager for published posts + eventobjects = EventObjects() # custom manager for published posts + class Meta: - ordering = ('-date_posted',) + ordering = ("-date_posted",) def __str__(self): return self.title diff --git a/backend/tests/test_models.py b/backend/tests/test_models.py index ccb43c84..294acbe4 100644 --- a/backend/tests/test_models.py +++ b/backend/tests/test_models.py @@ -5,52 +5,66 @@ class TestCreateEvent(TestCase): - @classmethod def setUpTestData(self): - test_category = Category.objects.create(name='django') + test_category = Category.objects.create(name="django") studentUser = User.objects.create_user( - username='test_user1', password='123456789') + username="test_user1", password="123456789" + ) mentorUser = User.objects.create_user( - username='test_user2', password='123456789') + username="test_user2", password="123456789" + ) # create some data for testing test_event = Event.objects.create( - category_id=1, title='Event Title', content='Event Content', - slug='event-title', student =studentUser, mentor=mentorUser, - start_date = timezone.now(), end_date=timezone.now(), status='published') - + category_id=1, + title="Event Title", + content="Event Content", + slug="event-title", + student=studentUser, + mentor=mentorUser, + start_date=timezone.now(), + end_date=timezone.now(), + status="published", + ) + # do some testing def test_event_content(self): event = Event.eventobjects.get(id=1) category = Category.objects.get(id=1) student_user = User.objects.get(id=1) mentor_user = User.objects.get(id=2) - self.assertEqual(f'{event.title}', 'Event Title') - self.assertEqual(f'{event.content}', 'Event Content') - self.assertEqual(f'{event.slug}', 'event-title') - self.assertEqual(f'{event.student}', 'test_user1') - self.assertEqual(f'{event.mentor}', 'test_user2') - self.assertEqual(f'{event.status}', 'published') - self.assertEqual(f'{category.name}', 'django') - self.assertEqual(f'{student_user.username}', 'test_user1') - self.assertEqual(f'{mentor_user.username}', 'test_user2') - - self.assertEqual(str(event), 'Event Title') - self.assertEqual(str(category), 'django') + self.assertEqual(f"{event.title}", "Event Title") + self.assertEqual(f"{event.content}", "Event Content") + self.assertEqual(f"{event.slug}", "event-title") + self.assertEqual(f"{event.student}", "test_user1") + self.assertEqual(f"{event.mentor}", "test_user2") + self.assertEqual(f"{event.status}", "published") + self.assertEqual(f"{category.name}", "django") + self.assertEqual(f"{student_user.username}", "test_user1") + self.assertEqual(f"{mentor_user.username}", "test_user2") + + self.assertEqual(str(event), "Event Title") + self.assertEqual(str(category), "django") def test_student(self): - test_user = Student.objects.create(first_name='Robera',last_name='Melaek',username='Melaek',password='Password',email='email@gmail.com',jnumber=1,role='student') + test_user = Student.objects.create( + first_name="Robera", + last_name="Melaek", + username="Melaek", + password="Password", + email="email@gmail.com", + jnumber=1, + role="student", + ) username = Student.objects.get(id=1) - self.assertEqual(f'{username.username}','Melaek') - self.assertEqual(f'{username.last_name}','Melaek') - self.assertEqual(f'{username.password}','Password') - self.assertEqual(f'{username.jnumber}','1') - self.assertEqual(f'{username.role}','student') - self.assertEqual(f'{username.email}','email@gmail.com') - self.assertEqual(f'{username.first_name}','Robera') - self.assertEqual(f'{username.student_id}','1') - - + self.assertEqual(f"{username.username}", "Melaek") + self.assertEqual(f"{username.last_name}", "Melaek") + self.assertEqual(f"{username.password}", "Password") + self.assertEqual(f"{username.jnumber}", "1") + self.assertEqual(f"{username.role}", "student") + self.assertEqual(f"{username.email}", "email@gmail.com") + self.assertEqual(f"{username.first_name}", "Robera") + self.assertEqual(f"{username.student_id}", "1") diff --git a/backend/urls.py b/backend/urls.py index 6aceddfe..b3b2aa77 100644 --- a/backend/urls.py +++ b/backend/urls.py @@ -2,5 +2,5 @@ from django.views.generic import TemplateView urlpatterns = [ - path('', TemplateView.as_view(template_name='backend/index.html')), + path("", TemplateView.as_view(template_name="backend/index.html")), ] diff --git a/core/asgi.py b/core/asgi.py index 76ae1d87..26a5940d 100644 --- a/core/asgi.py +++ b/core/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") application = get_asgi_application() diff --git a/core/settings.py b/core/settings.py index a8a6d0cb..1c32d1fa 100644 --- a/core/settings.py +++ b/core/settings.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-wpl5&=q^w8m$*9ge26^4qg#0g)6c#n8jv!)#v22m%b3^7w8pdf' +SECRET_KEY = "django-insecure-wpl5&=q^w8m$*9ge26^4qg#0g)6c#n8jv!)#v22m%b3^7w8pdf" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -32,62 +32,61 @@ # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'api', - 'backend', - 'rest_framework', - 'corsheaders', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "api", + "backend", + "rest_framework", + "corsheaders", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "corsheaders.middleware.CorsMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'core.urls' +ROOT_URLCONF = "core.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [BASE_DIR / 'template'], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [BASE_DIR / "template"], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'core.wsgi.application' +WSGI_APPLICATION = "core.wsgi.application" # DatabasE # https://docs.djangoproject.com/en/4.1/ref/settings/#databases DATABASES = { - - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.environ.get('POSTGRES_DB'), - 'USER': os.environ.get('POSTGRES_USER'), - 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), - 'HOST': 'db', - 'PORT': 5432, + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_DB"), + "USER": os.environ.get("POSTGRES_USER"), + "PASSWORD": os.environ.get("POSTGRES_PASSWORD"), + "HOST": "db", + "PORT": 5432, } } @@ -97,16 +96,16 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -114,9 +113,9 @@ # Internationalization # https://docs.djangoproject.com/en/4.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -126,20 +125,20 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.1/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = "static/" # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # This is the default value for the `DEFAULT_AUTHENTICATION_CLASSES` setting. # It is used when the `DEFAULT_AUTHENTICATION_CLASSES` setting is not defined. # It is a list of authentication classes that should be used for all views # TODO: Add your authentication classes here REST_FRAMEWORK = { - 'DEFAULT_PERMISSION_CLASSES': [ - 'rest_framework.permissions.AllowAny', + "DEFAULT_PERMISSION_CLASSES": [ + "rest_framework.permissions.AllowAny", ], } @@ -151,8 +150,8 @@ "http://localhost:3002", ] -# FIXME: Admin password and username +# FIXME: Admin password and username # Password: admin # username: admin -REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'} +REST_FRAMEWORK = {"DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema"} diff --git a/core/urls.py b/core/urls.py index 6584e885..bcbf19ee 100644 --- a/core/urls.py +++ b/core/urls.py @@ -16,18 +16,26 @@ from django.contrib import admin from rest_framework.schemas import get_schema_view from rest_framework.documentation import include_docs_urls -from django.urls import path, include +from django.urls import path, include urlpatterns = [ - path('', include('backend.urls')), # namespace='api' is not supported in Django 4.1 - path('api/', include('api.urls')), # namespace='api' is not supported in Django 4.1 - path('admin/', admin.site.urls), - path('docs/', include_docs_urls(title='Sap-API', description='This is the API for the Sap-web project. You will be able to find all the endpoints here.')), - path('schema', get_schema_view( - title="Sap-web-API", - description="This is the API for the Sap-web project", - version="1.0.0" - ), name='openapi-schema'), + path("", include("backend.urls")), # namespace='api' is not supported in Django 4.1 + path("api/", include("api.urls")), # namespace='api' is not supported in Django 4.1 + path("admin/", admin.site.urls), + path( + "docs/", + include_docs_urls( + title="Sap-API", + description="This is the API for the Sap-web project. You will be able to find all the endpoints here.", + ), + ), + path( + "schema", + get_schema_view( + title="Sap-web-API", + description="This is the API for the Sap-web project", + version="1.0.0", + ), + name="openapi-schema", + ), ] - - diff --git a/core/wsgi.py b/core/wsgi.py index 63bb0999..e9b9d8a4 100644 --- a/core/wsgi.py +++ b/core/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") application = get_wsgi_application() diff --git a/frontend/.devcontainer.json b/frontend/.devcontainer.json index 789ee58a..af6b220f 100644 --- a/frontend/.devcontainer.json +++ b/frontend/.devcontainer.json @@ -15,18 +15,19 @@ // Set *default* container specific settings.json values on container create. "settings": { - "editor.formatOnSave": false, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.fontFamily": "Cascadia Code, Fira Code", - "[markdown]": { - "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" - }, - "grammarly.files.include": ["**/*.md", "**/*.txt"] + "editor.formatOnSave": false, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.fontFamily": "Cascadia Code, Fira Code", + "[markdown]": { + "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" + }, + "grammarly.files.include": ["**/*.md", "**/*.txt"] }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "znck.grammarly", // https://marketplace.visualstudio.com/items?itemName=znck.grammarly + "znck.grammarly", // https://marketplace.visualstudio.com/items?itemName=znck.grammarly + "eamodio.gitlens", "github.copilot", "esbenp.prettier-vscode", "gruntfuggly.todo-tree", diff --git a/frontend/.pretterignore b/frontend/.prettierignore similarity index 95% rename from frontend/.pretterignore rename to frontend/.prettierignore index 0959a1f1..4549b307 100644 --- a/frontend/.pretterignore +++ b/frontend/.prettierignore @@ -2,6 +2,7 @@ node_modules/ build/ +htmlcov/* dist/ coverage/ @@ -28,7 +29,7 @@ yarn.lock *.ts # Others - *.json *.html *.css + diff --git a/frontend/.vscode/.prettierrc b/frontend/.vscode/.prettierrc index 222861c3..6ff95e36 100644 --- a/frontend/.vscode/.prettierrc +++ b/frontend/.vscode/.prettierrc @@ -1,4 +1,13 @@ { "tabWidth": 2, - "useTabs": false + "arrowParens": "always", + "bracketSpacing": true, + "overrides": [ + { + "files": "*.json", + "options": { + "tabWidth": 4 + } + } + ] } diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json index 34fb126b..c4ea31c7 100644 --- a/frontend/.vscode/launch.json +++ b/frontend/.vscode/launch.json @@ -1,28 +1,28 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Debug UI", - "request": "launch", - "type": "chrome", - "url": "http://localhost:3000", - "webRoot": "${workspaceFolder}" - }, - { - "name": "Debug Typescript(UI)", - "request": "launch", - "type": "chrome", - "url": "http://localhost:3000", - "webRoot": "${workspaceFolder}", - "sourceMaps": true, - "preLaunchTask": "tsc: build - tsconfig.dev.json", - "outFiles": ["${workspaceFolder}/dist/**/*.js"], - "smartStep": true, - //FIXME: to skip the javascript files - "skipFiles": ["node_modules/**", "dist/**", "build/**"] - } - ] + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug UI", + "request": "launch", + "type": "chrome", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + }, + { + "name": "Debug Typescript(UI)", + "request": "launch", + "type": "chrome", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}", + "sourceMaps": true, + "preLaunchTask": "tsc: build - tsconfig.dev.json", + "outFiles": ["${workspaceFolder}/dist/**/*.js"], + "smartStep": true, + //FIXME: to skip the javascript files + "skipFiles": ["node_modules/**", "dist/**", "build/**"] + } + ] } diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 0f230324..8f9bcc5e 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -1,4 +1,13 @@ { - "editor.defaultFormatter": "vscode.typescript-language-features", - "editor.formatOnSave": true + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.formatOnType": true, + "[json]": { + "editor.quickSuggestions": { + "strings": true + }, + "editor.suggest.insertMode": "replace", + "editor.tabSize": 4 + } } diff --git a/frontend/.vscode/tasks.json b/frontend/.vscode/tasks.json index 06325006..f4a0f885 100644 --- a/frontend/.vscode/tasks.json +++ b/frontend/.vscode/tasks.json @@ -1,16 +1,16 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "typescript", - "tsconfig": "tsconfig.json", - "option": "watch", - "problemMatcher": ["$tsc-watch"], - "group": { - "kind": "build", - "isDefault": true - }, - "label": "tsc: watch - tsconfig.json" - } - ] + "version": "2.0.0", + "tasks": [ + { + "type": "typescript", + "tsconfig": "tsconfig.json", + "option": "watch", + "problemMatcher": ["$tsc-watch"], + "group": { + "kind": "build", + "isDefault": true + }, + "label": "tsc: watch - tsconfig.json" + } + ] } diff --git a/frontend/install-dev-packages.sh b/frontend/install-dev-packages.sh index d6be190e..630f540a 100644 --- a/frontend/install-dev-packages.sh +++ b/frontend/install-dev-packages.sh @@ -1,7 +1,8 @@ #!/bin/ash # Install the necessary debugging tools (e.g., Node.js inspector) -apk add --no-cache nodejs npm +apk add --no-cache nodejs npm git npm install -g ts-node npm install -g nodemon npm install -g npmvet +npm install --save-dev --save-exact prettier diff --git a/frontend/npm-shrinkwrap.json b/frontend/npm-shrinkwrap.json index 9a6eb549..6ea54c9a 100644 --- a/frontend/npm-shrinkwrap.json +++ b/frontend/npm-shrinkwrap.json @@ -4497,9 +4497,7 @@ }, "node_modules/ansi-html-community": { "version": "0.0.8", - "engines": [ - "node >= 0.8.0" - ], + "engines": ["node >= 0.8.0"], "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" @@ -7663,9 +7661,7 @@ "version": "2.3.2", "license": "MIT", "optional": true, - "os": [ - "darwin" - ], + "os": ["darwin"], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 3ecd71e5..23eadde5 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { render, RenderResult, waitFor } from '@testing-library/react'; -import ConnectionExample from './App'; +import React from "react"; +import { render, RenderResult, waitFor } from "@testing-library/react"; +import ConnectionExample from "./App"; // This should make the `toBeInTheDocument` matcher available in the test environment import "@testing-library/jest-dom/extend-expect"; @@ -9,18 +9,16 @@ import "@testing-library/jest-dom/extend-expect"; // This should make the `waitFor` function available in the test environment import "mutationobserver-shim"; - // test('renders learn react link', () => { // render(); // const linkElement = screen.getByText(/learn react/i); // expect(linkElement).toBeInTheDocument(); // }); - -describe('ConnectionExample component', () => { +describe("ConnectionExample component", () => { beforeEach(() => { - jest.spyOn(global, 'fetch').mockResolvedValue({ - json: jest.fn().mockResolvedValue([{ id: 1, name: 'test' }]), + jest.spyOn(global, "fetch").mockResolvedValue({ + json: jest.fn().mockResolvedValue([{ id: 1, name: "test" }]), } as any); }); @@ -28,10 +26,10 @@ describe('ConnectionExample component', () => { jest.restoreAllMocks(); }); - it('should fetch data from server and render component', async () => { + it("should fetch data from server and render component", async () => { const component: RenderResult = render(); await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(1)); expect(global.fetch).toHaveBeenCalledWith("http://localhost:8000/api/"); - expect(component.getByText('Connection Example')).toBeInTheDocument(); + expect(component.getByText("Connection Example")).toBeInTheDocument(); }); -}); \ No newline at end of file +}); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0a750334..acb0915f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,14 +1,14 @@ import React from "react"; -import './App.css'; +import "./App.css"; import Calendar from "./Calendar"; // TODO: create a function to send request to the server to get the data class ConnectionExample extends React.Component { componentDidMount(): void { // TODO: send request to the server to get the data - fetch('http://localhost:8000/api/') - .then(response => response.json()) - .then(data => console.log(data)); + fetch("http://localhost:8000/api/") + .then((response) => response.json()) + .then((data) => console.log(data)); } render() { return ( @@ -20,5 +20,4 @@ class ConnectionExample extends React.Component { } } - export default ConnectionExample; diff --git a/frontend/src/Calendar.test.tsx b/frontend/src/Calendar.test.tsx index 2a899f34..a1549089 100644 --- a/frontend/src/Calendar.test.tsx +++ b/frontend/src/Calendar.test.tsx @@ -1,22 +1,22 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import Calendar from './Calendar'; +import React from "react"; +import { render, screen } from "@testing-library/react"; +import Calendar from "./Calendar"; -describe('Calendar', () => { - test('renders the calendar with the correct number of days', () => { +describe("Calendar", () => { + test("renders the calendar with the correct number of days", () => { render(); // Get all the day cells in the calendar - const dayCells = screen.getAllByTestId('day-cell'); + const dayCells = screen.getAllByTestId("day-cell"); // Make sure there are 42 day cells // expect(dayCells.length).toBe(42); expect(dayCells.length).toBe(35); }); - it('clicking a day cell sets the selected date', () => { + it("clicking a day cell sets the selected date", () => { const { getByText, queryByTestId } = render(); - const day = '15'; + const day = "15"; // Find the day cell const dayCell = queryByTestId(`day-cell-${day}`); diff --git a/frontend/src/Calendar.tsx b/frontend/src/Calendar.tsx index b6ad981a..987d3c55 100644 --- a/frontend/src/Calendar.tsx +++ b/frontend/src/Calendar.tsx @@ -1,10 +1,9 @@ -import React, { useState } from 'react'; -import dayjs, { Dayjs } from 'dayjs'; -import 'dayjs/locale/en'; // import your desired locale -import './Calendar.css'; +import React, { useState } from "react"; +import dayjs, { Dayjs } from "dayjs"; +import "dayjs/locale/en"; // import your desired locale +import "./Calendar.css"; - -dayjs.locale('en'); // set the locale globally +dayjs.locale("en"); // set the locale globally //TODO: Defining interface // interface Props { @@ -12,13 +11,11 @@ dayjs.locale('en'); // set the locale globally // setCurrentMonth: (date: Dayjs) => void; // } - // Defining the Calendar component const Calendar = () => { - - // Defining the weeksInMonth function + // Defining the weeksInMonth function const weeksInMonthCurrent = (date: Dayjs) => { - const firstDay = date.startOf('month').day(); + const firstDay = date.startOf("month").day(); const daysInMonth = date.daysInMonth(); return Math.ceil((firstDay + daysInMonth) / 7); }; @@ -26,27 +23,28 @@ const Calendar = () => { // Defining the state const [currentMonth, setCurrentMonth] = useState(dayjs()); const weeksInMonth: number = weeksInMonthCurrent(currentMonth); - const startOfMonth: Dayjs = currentMonth.startOf('month'); - const endOfMonth: Dayjs = currentMonth.endOf('month'); + const startOfMonth: Dayjs = currentMonth.startOf("month"); + const endOfMonth: Dayjs = currentMonth.endOf("month"); const daysInMonth: number = endOfMonth.date(); const daysInPrevMonth: number = startOfMonth.day(); const daysInNextMonth: number = 7 - endOfMonth.day() - 1; // Defining the prevMonth and nextMonth functions - const prevMonth = (): void => setCurrentMonth(currentMonth.subtract(1, 'month')); - const nextMonth = (): void => setCurrentMonth(currentMonth.add(1, 'month')); + const prevMonth = (): void => + setCurrentMonth(currentMonth.subtract(1, "month")); + const nextMonth = (): void => setCurrentMonth(currentMonth.add(1, "month")); // Defining the generateDaysArray function const generateDaysArray = (): (string | number)[] => { const daysArray: (string | number)[] = []; for (let i = 0; i < daysInPrevMonth; i++) { - daysArray.push(''); + daysArray.push(""); } for (let i = 1; i <= daysInMonth; i++) { daysArray.push(i); } for (let i = 0; i < daysInNextMonth; i++) { - daysArray.push(''); + daysArray.push(""); } return daysArray; }; @@ -66,35 +64,36 @@ const Calendar = () => { }); return weeksArray.map((week: (string | number)[], index: number) => ( -
- +
{week.map((day: string | number, index: number) => ( -
{day}
+
+ {day} +
))}
)); }; return ( -
-
-

{currentMonth.format('MMMM YYYY')}

+
+
+

{currentMonth.format("MMMM YYYY")}

-
-
sun
-
Mon
-
Tue
-
Wed
-
Thu
-
Fri
-
Sat
+
+
sun
+
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
{renderDays()} -
+
); }; diff --git a/frontend/src/SignIn.test.tsx b/frontend/src/SignIn.test.tsx index e77a4485..114af3e7 100644 --- a/frontend/src/SignIn.test.tsx +++ b/frontend/src/SignIn.test.tsx @@ -1,31 +1,31 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import SignIn from './SignIn'; +import React from "react"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import SignIn from "./SignIn"; import "@testing-library/jest-dom/extend-expect"; -test('renders sign in form', () => { +test("renders sign in form", () => { // Render the component render(); // Check if the heading "Sign in" is present - const heading = screen.getByRole('heading', { name: /Sign in/i }); + const heading = screen.getByRole("heading", { name: /Sign in/i }); expect(heading).toBeInTheDocument(); // Check if the email and password inputs are present - const emailInput = screen.getByLabelText('Email Address'); + const emailInput = screen.getByLabelText("Email Address"); console.log(emailInput); expect(emailInput).toBeInTheDocument(); - const passwordInput = screen.getByLabelText('Password'); + const passwordInput = screen.getByLabelText("Password"); expect(passwordInput).toBeInTheDocument(); // Fill in the email and password inputs - userEvent.type(emailInput, 'test@example.com'); - userEvent.type(passwordInput, 'password123'); + userEvent.type(emailInput, "test@example.com"); + userEvent.type(passwordInput, "password123"); // Check if the "Sign In" button is present - const signInButton = screen.getByRole('button', { name: /Sign In/i }); + const signInButton = screen.getByRole("button", { name: /Sign In/i }); expect(signInButton).toBeInTheDocument(); // Click the "Sign In" button diff --git a/frontend/src/SignIn.tsx b/frontend/src/SignIn.tsx index f8c56867..95ea7cc2 100644 --- a/frontend/src/SignIn.tsx +++ b/frontend/src/SignIn.tsx @@ -1,19 +1,19 @@ -import * as React from 'react'; -import Avatar from '@mui/material/Avatar'; -import Button from '@mui/material/Button'; -import CssBaseline from '@mui/material/CssBaseline'; +import * as React from "react"; +import Avatar from "@mui/material/Avatar"; +import Button from "@mui/material/Button"; +import CssBaseline from "@mui/material/CssBaseline"; // import TextField from '@mui/material/TextField'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import Checkbox from '@mui/material/Checkbox'; -import Link from '@mui/material/Link'; -import Grid from '@mui/material/Grid'; -import Box from '@mui/material/Box'; -import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; -import Typography from '@mui/material/Typography'; -import Container from '@mui/material/Container'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { SyntheticEvent, useState } from 'react'; -import { FormControl, Input, InputLabel } from '@mui/material'; +import FormControlLabel from "@mui/material/FormControlLabel"; +import Checkbox from "@mui/material/Checkbox"; +import Link from "@mui/material/Link"; +import Grid from "@mui/material/Grid"; +import Box from "@mui/material/Box"; +import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; +import Typography from "@mui/material/Typography"; +import Container from "@mui/material/Container"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; +import { SyntheticEvent, useState } from "react"; +import { FormControl, Input, InputLabel } from "@mui/material"; interface State { email: string; @@ -27,19 +27,19 @@ interface Props { const theme = createTheme(); -// TODO: console log and check in the input are +// TODO: console log and check in the input are // begin send at each stage export default function SignIn(props: Props) { const [state, setState] = useState({ - email: '', - password: '', + email: "", + password: "", rememberMe: false, }); const handleChange = (event: SyntheticEvent) => { const target = event.target as HTMLInputElement; const name = target.name; - const value = target.type === 'checkbox' ? target.checked : target.value; + const value = target.type === "checkbox" ? target.checked : target.value; setState({ ...state, @@ -59,18 +59,23 @@ export default function SignIn(props: Props) { - + Sign in - + Email Address } + /> + } label="Remember me" /> diff --git a/frontend/src/components/Events.tsx b/frontend/src/components/Events.tsx index 0a8977ac..24a14eb7 100644 --- a/frontend/src/components/Events.tsx +++ b/frontend/src/components/Events.tsx @@ -1,3 +1,3 @@ -import React from 'react'; +import React from "react"; -export {}; \ No newline at end of file +export {}; diff --git a/frontend/src/components/EventsLoading.tsx b/frontend/src/components/EventsLoading.tsx index 50e32652..261b3ae0 100644 --- a/frontend/src/components/EventsLoading.tsx +++ b/frontend/src/components/EventsLoading.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; export const EventsLoading = () => { return ( @@ -8,4 +8,4 @@ export const EventsLoading = () => { ); }; -// Path: src/components/Events.tsx \ No newline at end of file +// Path: src/components/Events.tsx diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index dbb6a495..2291f9af 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -6,7 +6,6 @@ import Link from "@mui/material/Link"; import GlobalStyles from "@mui/material/GlobalStyles"; import Container from "@mui/material/Container"; - function Copyright(props: any) { return ( - + {/* Footer */} `1px solid ${theme.palette.divider}` }} > - + Company name - @@ -61,26 +60,20 @@ function Header() { } const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement + document.getElementById("root") as HTMLElement ); const signInHandler = () => { console.log("signInHandler"); root.render( - < SignIn onSignIn={function (email: string, password: string): void { - throw new Error("Function not implemented."); - }} /> + ); -} - +}; export default Header; - - - - - - - diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 7aa04f5d..86174ac4 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,19 +1,18 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import Header from './components/Header'; -import Footer from './components/Footer'; - +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import Header from "./components/Header"; +import Footer from "./components/Footer"; const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement + document.getElementById("root") as HTMLElement ); root.render(
- < App /> - < Footer /> + +