First version
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
23
CTOAsYouGo/core/forms.py
Normal file
23
CTOAsYouGo/core/forms.py
Normal 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.")
|
||||
@@ -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',
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
@@ -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] + "..."
|
||||
|
||||
|
||||
BIN
CTOAsYouGo/core/templates/core/.task_detail.html.swp
Normal file
BIN
CTOAsYouGo/core/templates/core/.task_detail.html.swp
Normal file
Binary file not shown.
@@ -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>© 2023 Saburly DOO, Hakije Turajlica 2, 7100 Sarajevo. Bosnia and Herzegovina. All rights reserved.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
34
CTOAsYouGo/core/templates/core/how_it_works.html
Normal file
34
CTOAsYouGo/core/templates/core/how_it_works.html
Normal 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 %}
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
26
CTOAsYouGo/core/templates/core/thankyou.html
Normal file
26
CTOAsYouGo/core/templates/core/thankyou.html
Normal 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 %}
|
||||
@@ -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 %}
|
||||
Binary file not shown.
Binary file not shown.
@@ -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'),
|
||||
]
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user