its DOOMed, coz CORS came here :'(

This commit is contained in:
KUB0570 2025-02-19 20:51:19 +01:00
parent e6c1430e48
commit b593f68b66
19 changed files with 215 additions and 29 deletions

13
TODO
View file

@ -1,24 +1,11 @@
Nastylovat:
- header nedrží
- footer
- lazyload načítat o něco dříve (neli zrušit alespoň mimo galerii)
Naprogramovat:
- tlačítko "načíst další aktuality" v komponentě News (možná přidat i novou stránku /aktuality
- přidat kalendář
- kotvičky
- přidat v galerii zvětsovač na obrázky
- přidat backend
- přidat databázi
- kontakty
- clanky
- kalendar
- přidat api
- přidat volání na api
Naplánovat:
- kurzy + cena: vyskakovací okno na rezervaci s jménem lekce? jak to vyřešit s kalendářem? (stránka /rezervace)
- změnit (logicky) pořadí komponent na hlavní stránce
Čeká na Ondru:
- Důležité kontakty + obrázky jak se dostat nebo vzdálenosti od městské dopravy? přidat do googlu

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View file

@ -46,11 +46,15 @@ DEBUG_TOOLBAR_PANELS = [
]
ALLOWED_HOSTS = [
"0.0.0.0", "localhost", "127.0.0.1",
"localhost",
]
INTERNAL_IPS = [
"0.0.0.0", "localhost", "127.0.0.1",
"localhost",
]
CORS_ALLOWED_ORIGINS = [
"http://localhost:8000",
]
# Application definition
@ -62,6 +66,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tko.apps.TkoConfig',
"debug_toolbar",
'rest_framework',
]

View file

@ -15,10 +15,14 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
from django.urls import path
from debug_toolbar.toolbar import debug_toolbar_urls
from tko.views import ContactView, ArticleListView, EventListView
urlpatterns = [
path('admin/', admin.site.urls),
path('create-contact/', ContactView.as_view(), name='create-contact'),
path('load-articles/', ArticleListView.as_view(), name='load-articles'),
path('load-events/', EventListView.as_view(), name='load-events'),
] + debug_toolbar_urls()

View file

@ -1,19 +1,29 @@
from django.contrib import admin
# Register your models here.
from . import models
@admin.register(models.Contact)
class ContactAdmin(admin.ModelAdmin):
fields = "__all__"
list_display = ['name', 'email', 'phone_number', 'content']
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return False
@admin.register(models.Article)
class ArticleAdmin(admin.ModelAdmin):
fields = "__all__"
list_display = ['title', 'date', 'author']
@admin.register(models.Event)
class EventAdmin(admin.ModelAdmin):
fields = "__all__"
list_display = ['title', 'start_date', 'end_date', 'color']

View file

@ -0,0 +1,46 @@
# Generated by Django 5.1.5 on 2025-02-19 16:16
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Article',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('content', models.TextField()),
('date', models.DateField()),
('author', models.CharField(max_length=100)),
('active_to', models.DateField(blank=True, null=True)),
],
),
migrations.CreateModel(
name='Contact',
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)),
('phone_number', models.CharField(max_length=16)),
('content', models.TextField()),
],
),
migrations.CreateModel(
name='Event',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('start_date', models.DateTimeField()),
('end_date', models.DateTimeField()),
('color', models.CharField(max_length=100)),
],
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 5.1.5 on 2025-02-19 16:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tko', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='article',
name='image',
field=models.FileField(null=True, upload_to='articles/%Y/%m/%d'),
),
]

View file

@ -0,0 +1,22 @@
# Generated by Django 5.1.5 on 2025-02-19 18:33
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tko', '0002_article_image'),
]
operations = [
migrations.RenameField(
model_name='contact',
old_name='first_name',
new_name='name',
),
migrations.RemoveField(
model_name='contact',
name='last_name',
),
]

View file

@ -2,25 +2,33 @@ from django.db import models
# Create your models here.
class Contact(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
name = models.CharField(max_length=100)
email = models.EmailField()
phone_number = models.CharField(max_length=16)
content = models.TextField()
def __str__(self):
return f"{self.name}, {self.email}, {self.phone_number}"
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
# image = models.ImageField(upload_to='articles/%Y/%m/%d')
image = models.FileField(upload_to='articles/%Y/%m/%d', null=True)
date = models.DateField()
author = models.CharField(max_length=100)
active_to = models.DateField(null=True, blank=True) # do not show some invitation after this date
def __str__(self):
return self.title
class Event(models.Model):
title = models.CharField(max_length=100)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
color = models.CharField(max_length=100)
def __str__(self):
return self.title

View file

@ -0,0 +1,21 @@
from rest_framework import serializers
from tko.models import Contact, Article, Event
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = '__all__'
class ArticleListSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = '__all__'
class EventListSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields = '__all__'

View file

@ -1,3 +1,22 @@
from django.shortcuts import render
from rest_framework.generics import ListAPIView, CreateAPIView
from rest_framework import permissions
# Create your views here.
from tko.models import Article, Event
from tko.serializers import ArticleListSerializer, EventListSerializer, ContactSerializer
class ContactView(CreateAPIView):
serializer_class = ContactSerializer
permission_classes = [permissions.AllowAny]
class ArticleListView(ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleListSerializer
permission_classes = [permissions.AllowAny]
class EventListView(ListAPIView):
queryset = Event.objects.all()
serializer_class = EventListSerializer
permission_classes = [permissions.AllowAny]

View file

@ -17,6 +17,10 @@
<script setup lang="ts">
import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const { error, data } = await useAPI('load-events/', {method: "GET"});
const value = [new Date()];
const events = [

View file

@ -1,6 +1,6 @@
<template>
<v-card class="contact">
<v-form v-model="valid" @submit="sendContact">
<v-form v-model="valid">
<v-container>
<v-card-title class="contact__title">Kontaktujte nás!</v-card-title>
<v-row>
@ -51,6 +51,7 @@
<v-btn
class="contact__button"
type="submit"
@click.prevent="sendContact"
>
Poslat
</v-btn>
@ -62,6 +63,7 @@
</template>
<script setup lang="ts">
import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const valid = ref<boolean>(false);
@ -71,7 +73,15 @@ const phone = ref<string>("");
const textField = ref<string>("");
function sendContact() {
console.log("KONTAKT NEZASLAN");
useAPI('create-contact/', {
method: "POST",
body: {
name: fullName.value,
email: email.value,
phone_number: phone.value,
content: textField.value,
}
});
}
</script>

View file

@ -44,6 +44,11 @@
<script setup lang="ts">
import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const { error, data } = await useAPI('load-articles/', {method: "GET"});
console.log(error.value);
const articles = [
{
autor: "Bebloid Obecný",

View file

@ -1,4 +1,5 @@
<template>
<ClientOnly>
<v-layout>
<v-app-bar style="position: fixed">
<v-app-bar-nav-icon
@ -49,8 +50,8 @@
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-layout>
</ClientOnly>
</template>
<script setup lang="ts">

View file

@ -0,0 +1,19 @@
import type { UseFetchOptions } from "nuxt/app";
export function useAPI<T>(
endpoint: string,
options?: UseFetchOptions<T>,
) {
if (!endpoint.startsWith("/")) {
endpoint = `/${endpoint}`
}
const cfg = useRuntimeConfig()
const fullUrl = `${cfg.public.backendUrl}${endpoint}`
return useFetch(
fullUrl,
{...options}
)
}

View file

@ -3,11 +3,17 @@ import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
ssr: false,
devtools: { enabled: true },
typescript: { typeCheck: true},
build: {
transpile: ['vuetify'],
},
runtimeConfig: {
public: {
backendUrl: process.env.BACKEND_URL ?? "http://localhost:8000"
},
},
modules: [
(_options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) => {

View file

@ -19,5 +19,7 @@
<courses/>
<contact-us/>
</template>
<script setup lang="ts">
</script>

View file

@ -66,6 +66,5 @@ export default defineNuxtPlugin((app) => {
}
})
app.vueApp.use(vuetify)
})