First version

This commit is contained in:
Senad Uka
2023-07-05 11:02:15 +02:00
parent f21c24b599
commit 8eabf79994
4052 changed files with 723968 additions and 232443 deletions

23
CTOAsYouGo/core/forms.py Normal file
View File

@@ -0,0 +1,23 @@
from django import forms
from django.core.exceptions import ValidationError
from .models import Request
class RequestForm(forms.ModelForm):
class Meta:
model = Request
fields = ['task', 'email', 'email_confirmation', 'description', 'price_from', 'price_to', 'needed_information', 'title']
widgets = {
'task': forms.HiddenInput(),
'price_from': forms.HiddenInput(),
'price_to': forms.HiddenInput(),
'needed_information': forms.HiddenInput(),
'title': forms.HiddenInput(),
}
def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get("email")
email_confirmation = cleaned_data.get("email_confirmation")
if email != email_confirmation:
raise ValidationError("Email confirmation does not match with the email.")

View File

@@ -0,0 +1,21 @@
# Generated by Django 4.2.2 on 2023-07-04 16:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='request',
name='comment',
),
migrations.RemoveField(
model_name='request',
name='start_in_days',
),
]

View File

@@ -19,9 +19,9 @@ class Request(models.Model):
price_from = models.IntegerField(validators=[MinValueValidator(0)])
price_to = models.IntegerField(validators=[MinValueValidator(0)])
needed_information = models.JSONField()
start_in_days = models.IntegerField()
email = models.EmailField()
email_confirmation = models.EmailField()
external_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
comment = models.TextField(null=True, blank=True)
def __str__(self):
return self.email + ' ' + self.title + " " + self.description[:20] + "..."

Binary file not shown.

View File

@@ -18,7 +18,7 @@
<div
class="mx-auto flex h-16 max-w-screen-xl items-center gap-8 px-4 sm:px-6 lg:px-8"
>
<a class="block text-teal-600 dark:text-teal-300" href="/">
<a class="block text-teal-600 dark:text-teal-300" href="{% url 'home' %}">
<span class="sr-only">Home</span>
<img src="{% static 'images/logo.png' %}" alt="cto as you go logo">
</a>
@@ -29,7 +29,7 @@
<div class="sm:flex sm:gap-4">
<a
class="block rounded-md bg-gray-100 px-5 py-2.5 text-sm font-medium text-teal-600 transition hover:text-teal-600/75 sm:block"
href="/why_it_works"
href="{% url 'how_it_works' %}"
>
How?
</a>
@@ -43,5 +43,9 @@
{% block content %}
{% endblock %}
<footer class="text-center text-gray-500 text-xs">
<p>&copy; 2023 Saburly DOO, Hakije Turajlica 2, 7100 Sarajevo. Bosnia and Herzegovina. All rights reserved.</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,34 @@
{% extends 'core/base.html' %}
{% block content %}
<article>
<h1 class="font-bold rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4 text-lg">How does it function?</h1>
<section class="rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4">
<h2>It's straightforward!</h2>
<ol class="max-w-md space-y-1 list-decimal list-inside">
<li>You send us a request for a service including basic details of the project</li>
<li>We contact you to ask about more details. We can do that either through email or through a video call - whichever you prefer. </li>
<li> We send you a quote for the project. It contains description of the content of the report you will get. With multiple options if possible.</li>
<li> You pay for the option you chose.</li>
<li> We start working deliver the report to you.</li>
<li> You confirm the satisfaction with the report or we refund your money.</li>
</ol>
</section>
<h2 class="font-bold rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4 text-lg">Network Of CTOs</h2>
<section class="rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4">
Throughout our work we have built a network of higlhy experienced individuals each with their own speciality. Our selection process choses the person most experienced with technical and business domain of your project.
Network also shares the knowledge inside of it so that no aspects are overlooked.
</section>
<h2 class="font-bold rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4 text-lg">Natural intelligence</h2>
<section class="rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4">
While we do love tehcnology, and use AI whenever it is helpful - every part of communication and thinking in our process is done by humans. AI is not there yet for the level we aim to provide.
</section>
</article>
{% endblock %}

View File

@@ -1,5 +1,7 @@
{% extends 'core/base.html' %}
{% load currency_filters %}
{% load widget_tweaks %}
{% block content %}
<article>
<h1 class="font-bold rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4 text-lg">{{ task.title }}</h1>
@@ -11,33 +13,39 @@
<section class="rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4">
<form class="">
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-first-name">
First Name
</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white" id="grid-first-name" type="text" placeholder="Jane">
<p class="text-red-500 text-xs italic">Please fill out this field.</p>
<form method="post" class="space-y-4">
{% csrf_token %}
<div class="hidden">
{{ form.task }}
{{ form.price_from }}
{{ form.price_to }}
{{ form.needed_information }}
{{ form.title }}
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full md:w-1/2 px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-last-name">
Last Name
</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-last-name" type="text" placeholder="Doe">
<div>
<label for="{{ form.email.id_for_label }}" class="block text-sm font-medium text-gray-700">
Email
</label>
{{ form.email|add_class:"mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" }}
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-2">
<div class="w-full md:w-1/3 px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
City
</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-city" type="text" placeholder="Albuquerque">
<div>
<label for="{{ form.email_confirmation.id_for_label }}" class="block text-sm font-medium text-gray-700">
Confirm Email
</label>
{{ form.email_confirmation|add_class:"mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" }}
</div>
</div>
<div>
<label for="{{ form.description.id_for_label }}" class="block text-sm font-medium text-gray-700">
Information about your specific needs
</label>
{{ form.description|add_class:"mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" }}
</div>
<button type="submit" class="btn btn-green">
Send request
</button>
</form>
</section>

View File

@@ -0,0 +1,26 @@
{% extends 'core/base.html' %}
{% load currency_filters %}
{% load widget_tweaks %}
{% block content %}
<article>
<h1 class="font-bold rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4 text-lg">Thank You.</h1>
<section class="rounded-xl border-2 border-gray-200 bg-slate-100 mb-3 ml-3 mr-3 p-4">
<p>One of our staff will contact you by email as soon as possible.</p>
<p>In the meantime you can: </p>
<br>
<div>
<a class="btn btn-green mr-1" href="{% url 'how_it_works' %}" class="text-blue-500">
Learn how our process works
</a>
or <a href="{% url 'home' %}" class="text-blue-500">return to the home page</a>
</section>
</article>
{% endblock %}

View File

@@ -1,6 +0,0 @@
{% extends 'core/base.html' %}
{% block content %}
<h1>Why it works?</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis volutpat sem, quis ultrices orci imperdiet sit amet.</p>
{% endblock %}

View File

@@ -5,5 +5,6 @@ urlpatterns = [
path('', views.home, name='home'),
path('task/<int:task_id>', views.task_detail, name='task_detail'),
path('task/<int:task_id>/create_request', views.create_request, name='create_request'),
path('why_it_works', views.why_it_works, name='why_it_works'),
path('how_it_works', views.how_it_works, name='how_it_works'),
path('thankyou', views.thankyou, name='thankyou'),
]

View File

@@ -1,23 +1,57 @@
from django.shortcuts import render
from .models import Task, Request
from .forms import RequestForm
from django.http import HttpResponseRedirect
from django.urls import reverse
def home(request):
tasks = Task.objects.all()
return render(request, 'core/home.html', {'tasks': tasks})
def thankyou(request):
return render(request, 'core/thankyou.html')
def task_detail(request, task_id):
task = Task.objects.get(id=task_id)
return render(request, 'core/task_detail.html', {'task': task})
if request.method == 'POST':
print("Checking form validity.")
form = RequestForm(request.POST)
if form.is_valid():
print("Form is valid.")
new_request = form.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('thankyou'))
else:
print(f"Form not valid. Errors: {form.errors}")
else:
form = RequestForm(initial={'task': task,'price_from': task.price_from, 'price_to': task.price_to, 'needed_information': task.needed_information,'title': task.title})
return render(request, 'core/task_detail.html', {'task': task, 'form': form})
#def create_request(request, task_id):
# if request.method == 'POST':
# # logic to create a new Request
# pass
# else:
# task = Task.objects.get(id=task_id)
# request_obj = Request().objects.create(task=task)
# return render(request, 'core/create_request.html', {'task': task})
def create_request(request, task_id):
task = Task.objects.get(id=task_id)
if request.method == 'POST':
# logic to create a new Request
pass
form = RequestForm(request.POST)
if form.is_valid():
new_request = form.save()
# redirect to a new URL:
return HttpResponseRedirect('/')
else:
task = Task.objects.get(id=task_id)
return render(request, 'core/create_request.html', {'task': task})
form = RequestForm(initial={'task': task})
def why_it_works(request):
return render(request, 'core/why_it_works.html')
return render(request, 'core/create_request.html', {'form': form})
def how_it_works(request):
return render(request, 'core/how_it_works.html')