Merge branch 'feature/33-use-css-for-header' into 'develop/0.2.0'

Resolve "use CSS for header"

Closes #33

See merge request tpeetz/kontor!35
This commit was merged in pull request #79.
This commit is contained in:
2025-08-16 00:40:32 +02:00
18 changed files with 464 additions and 162 deletions
+172
View File
@@ -0,0 +1,172 @@
* {
box-sizing: border-box;
}
body {
font-family: Arial;
padding: 10px;
background: lightgrey;
}
/* Header/Blog Title */
.header {
padding: 30px;
text-align: center;
background-color: lightblue;
}
.header h1 {
font-size: 50px;
}
/* Style the top navigation bar */
.topnav {
overflow: hidden;
background-color: darkgrey;
}
/* Style the topnav links */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change color on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
.subnav {
overflow: hidden;
background-color: grey;
}
.subnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center;
padding-top: 10px;
padding-left: 20px;
}
.form-inline label {
margin: 5px 10px 5px 0;
}
.form-inline input {
padding-right: 50px;
margin-right: 10px;
}
.form-inline button {
padding: 10px 20px;
background-color: dodgerblue;
border: 1px solid #ddd;
color: white;
border-radius: 10px;
}
.form-inline button:hover {
background-color: royalblue;
}
.pill-nav a {
display: inline-block;
color: white;
background-color: dodgerblue;
text-align: center;
padding: 10px;
text-decoration: none;
border-radius: 10px;
margin-left: 20px;
}
/* Change the color of links on mouse-over */
.pill-nav a:hover {
background-color: royalblue;
color: white;
}
/* Add a color to the active/current link */
.pill-nav a.active {
background-color: royalblue;
color: white;
}
.maincolumn {
float:left;
width: 100%;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
background-color: #f1f1f1;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row::after {
content: "";
display: table;
clear: both;
}
/* Footer */
.footer {
padding: 20px;
text-align: center;
background: #ddd;
margin-top: 20px;
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
.topnav a {
float: none;
width: 100%;
}
}
+30 -17
View File
@@ -4,23 +4,39 @@
<title>Comic List</title> <title>Comic List</title>
{% endblock %} {% endblock %}
{% block header %}
<h1>Comics..</Comics></h1>
{% endblock %}
{% block subnav %}
<div class="subnav">
<a href="/comic/artists/">Artists</a>
<a href="/comic/publishers/">Publishers</a>
<a href="/comic/worktypes">WorkTypes</a>
</div>
{% endblock %}
{% block content %} {% block content %}
{% with msg=msg %} {% with msg=msg %}
{% include "components/alerts.html" %} {% include "components/alerts.html" %}
{% endwith %} {% endwith %}
<div class="container"> <div class="row">
<div class="row"> <form class="form-inline" action="/comic/comics">
<form class="d-flex" action="/comic/comics/"> <input type="text" placeholder="Search" name="query">
<input class="form-control me-2" name="query" id="autocomplete" type="search" placeholder="Search" aria-label="Search"> <label>
Completed<input type="checkbox" name="completed" {% if request.query_params.get("completed")=="on" %}checked{% endif %} aria-label="Completed"> <input type="checkbox" name="completed" {% if request.query_params.get("completed")=="on" %}checked{% endif %}>Completed
Order<input type="checkbox" name="order" {% if request.query_params.get("order")=="on" %}checked{% endif %} aria-label="Order"> </label>
<button class="btn btn-outline-success" type="submit">Search</button> <label>
</form> <input type="checkbox" name="order" {% if request.query_params.get("order")=="on" %}checked{% endif %}>Order
</div> </label>
<div class="row"> <button type="submit">Search</button>
<h1 class="display-5">Comics..</h1> <div class="pill-nav">
</div> <a href="/comic/comic/add">Add Comic</a>
<div class="row"> </div>
</form>
</div>
<div class="row">
<div class="maincolumn">
<table class="table table-hover"> <table class="table table-hover">
<thead><tr> <thead><tr>
<th scope="col">Title</th> <th scope="col">Title</th>
@@ -36,13 +52,10 @@
<td>{% with check=comic.completed %}{% include "components/check.html" %}{% endwith %}</td> <td>{% with check=comic.completed %}{% include "components/check.html" %}{% endwith %}</td>
<td><a href="/comic/comics/edit/{{comic.id}}" class="btn btn-outline-primary btn-sm active" role="button" aria-pressed="true">Edit</a></td> <td><a href="/comic/comics/edit/{{comic.id}}" class="btn btn-outline-primary btn-sm active" role="button" aria-pressed="true">Edit</a></td>
<td><a href="/comic/comics/delete/{{comic.id}}" class="btn btn-outline-danger btn-sm active" role="button" aria-pressed="true">Delete</a></td> <td><a href="/comic/comics/delete/{{comic.id}}" class="btn btn-outline-danger btn-sm active" role="button" aria-pressed="true">Delete</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div>
<a href="/comic/comic/add" class="btn btn-outline-primary btn-sm active" role="button" aria-pressed="true">Add Comic</a>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -0,0 +1 @@
<h2>Footer</h2>
@@ -1,4 +1,12 @@
<nav class="navbar navbar-expand-lg navbar-light bg-light px-5"> <div class="topnav">
<a href="/">Kontor</a>
<a href="/comic/comics">Comics</a>
<a href="/media/files">Media</a>
<a style="float:right" href="/login/">Login</a></li>
</div>
<!-- <nav class="navbar navbar-expand-lg navbar-light bg-light px-5">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" href="#">Kontor</a> <a class="navbar-brand" href="#">Kontor</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
@@ -63,4 +71,4 @@
</form> </form>
</div> </div>
</div> </div>
</nav> </nav> -->
+3
View File
@@ -5,6 +5,9 @@
<title>Kontor</title> <title>Kontor</title>
{% endblock %} {% endblock %}
{% block header %}
<h1>Kontor</h1>
{% endblock %}
{% block content %} {% block content %}
{% with msg=msg %} {% with msg=msg %}
{% include "components/alerts.html" %} {% include "components/alerts.html" %}
+30 -12
View File
@@ -4,34 +4,52 @@
<title>MediaFiles List</title> <title>MediaFiles List</title>
{% endblock %} {% endblock %}
{% block header %}
<h1>MediaFiles..</h1>
{% endblock %}
{% block subnav %}
{% include "media/media_nav.html" %}
{% endblock %}
{% block content %} {% block content %}
{% with msg=msg %} {% with msg=msg %}
{% include "components/alerts.html" %} {% include "components/alerts.html" %}
{% endwith %} {% endwith %}
<div class="container"> <div class="row">
<div class="row"> <form class="form-inline" action="/media/files">
<form class="d-flex" action="/media/files/"> <input type="text" placeholder="Search" name="query">
<input class="form-control me-2" name="query" id="autocomplete" type="search" placeholder="Search" aria-label="Search"> <label>
Review<input type="checkbox" name="review" aria-label="Review"> <input type="checkbox" name="review" {% if request.query_params.get("review")=="on" %}checked{% endif %}>Review
Download<input type="checkbox" name="download" aria-label="Download"> </label>
<button class="btn btn-outline-success" type="submit">Search</button> <label>
</form> <input type="checkbox" name="download" {% if request.query_params.get("download")=="on" %}checked{% endif %}>Download
</div> </label>
<div class="row"> <button type="submit">Search</button>
<div class="pill-nav">
<a href="/media/files/add">Add MediaFile</a>
</div>
</form>
</div>
<div class="row">
<div class="maincolumn">
<table class="table table-hover"> <table class="table table-hover">
<thead><tr> <thead><tr>
<th scope="col">Titel</th> <th scope="col">Titel</th>
<th scope="col">Review</th> <th scope="col">Review</th>
<th scope="col">Download</th> <th scope="col">Download</th>
<th colspan="2">Actions</th>
</tr></thead> </tr></thead>
<tbody> <tbody>
{% for mediafile in mediafiles %} {% for mediafile in mediafiles %}
<tr> <tr>
<th scope="row"><a href="/media/files/{{mediafile.id}}">{{mediafile.title}}</a></th> <th scope="row"><a href="/media/files/{{mediafile.id}}">{{mediafile.title}}</a></th>
<td>{% with check=mediafile.review %}{% include "components/check.html" %}{% endwith %}</td> <td>{% with check=mediafile.review %}{% include "components/check.html" %}{% endwith %}</td>
<td>{% with check=mediafile.should_download %}{% include "components/check.html" %}{% endwith %}</td> <td>{% with check=mediafile.should_download %}{% include "components/check.html" %}{% endwith %}</td>
<td><a href="/media/files/edit/{{mediafile.id}}" class="btn btn-outline-primary btn-sm active" role="button" aria-pressed="true">Edit</a></td>
<td><a href="/media/files/delete/{{mediafile.id}}" class="btn btn-outline-danger btn-sm active" role="button" aria-pressed="true">Delete</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
@@ -0,0 +1,5 @@
<div class="subnav">
<a href="/media/files/">MediaFiles</a>
<a href="/media/actors/">MediaActors</a>
<a href="/media/videos/">MediaVideos</a>
</div>
+69 -19
View File
@@ -1,25 +1,75 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de-DE"> <html lang="de-DE">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <link rel="stylesheet" href="{{ url_for('static', path='style.css') }}">
{% block title %} {% block title %}
{% endblock %} {% endblock %}
</head> </head>
<body> <body>
{% include "components/navbar.html" %} <div class="header">
{% block content %} {% block header %}
{% endblock %} {% endblock %}
</div>
{% include "components/navbar.html" %}
{% block subnav %}
{% endblock %}
<!-- <div class="topnav">
<a href="#">Link</a>
<a href="#">Link</a>
<a href="#">Link</a>
<a href="#" style="float:right">Link</a>
</div> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script> {% block content %}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> {% endblock %}
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="{{ url_for('static', path='js/autocomplete.js') }}"></script>
{% block scripts %}
{% endblock %}
</body> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
<script src="{{ url_for('static', path='js/autocomplete.js') }}"></script>
{% block scripts %}
{% endblock %}
<!-- <div class="row">
<div class="leftcolumn">
<div class="card">
<h2>TITLE HEADING</h2>
<h5>Title description, Dec 7, 2017</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
<div class="card">
<h2>TITLE HEADING</h2>
<h5>Title description, Sep 2, 2017</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
</div>
<div class="rightcolumn">
<div class="card">
<h2>About Me</h2>
<div class="fakeimg" style="height:100px;">Image</div>
<p>Some text about me in culpa qui officia deserunt mollit anim..</p>
</div>
<div class="card">
<h3>Popular Post</h3>
<div class="fakeimg"><p>Image</p></div>
<div class="fakeimg"><p>Image</p></div>
<div class="fakeimg"><p>Image</p></div>
</div>
<div class="card">
<h3>Follow Me</h3>
<p>Some text..</p>
</div>
</div>
</div> -->
<div class="footer">
{% include "components/footer.html" %}
</div>
</body>
</html> </html>
@@ -29,7 +29,7 @@ def add_worktype(request: Request, db: SessionDep):
return templates.TemplateResponse("comic/worktype_edit.html", {"request": request}) return templates.TemplateResponse("comic/worktype_edit.html", {"request": request})
@router.post("/worktype/add") @router.post("/worktype/add")
async def add_worktype(db: SessionDep, request: Request): async def add_worktype_post(db: SessionDep, request: Request):
form = AddWorktypeForm(request) form = AddWorktypeForm(request)
await form.load_data() await form.load_data()
if form.is_valid(): if form.is_valid():
@@ -47,11 +47,11 @@ async def add_worktype(db: SessionDep, request: Request):
@router.get("/worktype/edit/{worktype_id}") @router.get("/worktype/edit/{worktype_id}")
def edit_worktype(db: SessionDep, request: Request, worktype_id: str): def edit_worktype(db: SessionDep, request: Request, worktype_id: str):
worktype = db.get(WorkType, worktype_id) worktype: WorkType | None = db.get(WorkType, worktype_id)
return templates.TemplateResponse("comic/worktype_edit.html", {"request": request, "worktype": worktype.name}) return templates.TemplateResponse("comic/worktype_edit.html", {"request": request, "worktype": worktype.name})
@router.post("/worktype/edit/{worktype_id}") @router.post("/worktype/edit/{worktype_id}")
async def edit_worktype(request: Request, db: SessionDep, worktype_id: str): async def edit_worktype_post(request: Request, db: SessionDep, worktype_id: str):
form = AddWorktypeForm(request) form = AddWorktypeForm(request)
await form.load_data() await form.load_data()
if form.is_valid(): if form.is_valid():
@@ -0,0 +1,24 @@
from typing import AnyStr
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from sqlalchemy import or_
from src.apis.utils import SessionDep
from src.db.models.media import MediaActor
from src.core.log_conf import logger
templates = Jinja2Templates(directory="src/templates")
router = APIRouter(include_in_schema=False, prefix="/media")
@router.get("/actors")
def get_actors(db: SessionDep, request: Request, msg: str | None = None):
actors = db.query(MediaActor).all()
return templates.TemplateResponse("media/actors.html", {"request": request, "msg": msg, "actors": actors})
@router.get("/actors/{actor_id}")
def artist_detail(actor_id: AnyStr, request: Request, db: SessionDep):
actor = db.get(MediaActor, actor_id)
return templates.TemplateResponse("media/actor_detail.html", {"request": request, "actor": actor})
+7 -10
View File
@@ -9,12 +9,13 @@ from src.apis.utils import SessionDep
from src.apis.version1.admin import get_current_user_from_token from src.apis.version1.admin import get_current_user_from_token
from src.db.models.admin import Profile from src.db.models.admin import Profile
from src.db.models.media import MediaFile, MediaActor from src.db.models.media import MediaFile, MediaActor
from src.core.log_conf import logger
templates = Jinja2Templates(directory="src/templates") templates = Jinja2Templates(directory="src/templates")
router = APIRouter(include_in_schema=False, prefix="/media") router = APIRouter(include_in_schema=False, prefix="/media")
@router.get("/files") @router.get("/files")
def get_mediafiles(db: SessionDep, request: Request, msg: str = None): def get_mediafiles(db: SessionDep, request: Request, msg: str | None = None):
params = request.query_params params = request.query_params
query = params.get("query") query = params.get("query")
filter = {} filter = {}
@@ -40,6 +41,7 @@ def get_mediafiles(db: SessionDep, request: Request, msg: str = None):
return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles}) return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles})
except Exception as e: except Exception as e:
print(e) print(e)
logger.info("User is not authorized, no data shown")
msg = "Nicht berechtigt!!" msg = "Nicht berechtigt!!"
return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": []}) return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": []})
@@ -48,13 +50,8 @@ def file_details(file_id: AnyStr, request: Request, db: SessionDep):
mediafile = db.get(MediaFile, file_id) mediafile = db.get(MediaFile, file_id)
return templates.TemplateResponse("media/file_detail.html", {"request": request, "mediafile":mediafile}) return templates.TemplateResponse("media/file_detail.html", {"request": request, "mediafile":mediafile})
@router.get("/actors") @router.get("files/edit/{file_id}")
def get_actors(db: SessionDep, request: Request, msg: str = None): def edit_file(db: SessionDep, request: Request, file_id: str):
actors = db.query(MediaActor).all() media_file = db.get(MediaFile, file_id)
return templates.TemplateResponse("media/actors.html", {"request": request, "msg": msg, "actors": actors}) return templates.TemplateResponse("media/file_detail.html", {"request": request, "mediafile":media_file})
@router.get("/actors/{actor_id}")
def artist_detail(actor_id: AnyStr, request: Request, db: SessionDep):
actor = db.get(MediaActor, actor_id)
return templates.TemplateResponse("media/actor_detail.html", {"request": request, "actor": actor})
+5 -5
View File
@@ -1,10 +1,10 @@
<!DOCTYPE html> <!doctype html>
<html lang=""> <html lang="">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title> <title>Kontor</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
+4 -46
View File
@@ -1,62 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router' import { RouterView } from 'vue-router'
import MainNavbar from '@/components/MainNavbar.vue'
</script> </script>
<template> <template>
<header> <header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /> <MainNavbar />
<div class="wrapper">
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
</div>
</header> </header>
<RouterView /> <RouterView />
</template> </template>
<style scoped> <style scoped>
header {
line-height: 1.5;
max-height: 100vh;
}
.logo {
display: block;
margin: 0 auto 2rem;
}
nav {
width: 100%;
font-size: 12px;
text-align: center;
margin-top: 2rem;
}
nav a.router-link-exact-active {
color: var(--color-text);
}
nav a.router-link-exact-active:hover {
background-color: transparent;
}
nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}
nav a:first-of-type {
border: 0;
}
@media (min-width: 1024px) { @media (min-width: 1024px) {
header { header {
display: flex; display: inline;
place-items: center; place-items: center;
padding-right: calc(var(--section-gap) / 2); padding-right: calc(var(--section-gap) / 2);
} }
+4 -39
View File
@@ -1,5 +1,5 @@
/* color palette from <https://github.com/vuejs/theme> */ /* color palette from <https://github.com/vuejs/theme> */
:root { /* :root {
--vt-c-white: #ffffff; --vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8; --vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2; --vt-c-white-mute: #f2f2f2;
@@ -19,7 +19,7 @@
--vt-c-text-light-2: rgba(60, 60, 60, 0.66); --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white); --vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64); --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
} } */
/* semantic color variables for this project */ /* semantic color variables for this project */
:root { :root {
@@ -36,7 +36,7 @@
--section-gap: 160px; --section-gap: 160px;
} }
@media (prefers-color-scheme: dark) { /* @media (prefers-color-scheme: dark) {
:root { :root {
--color-background: var(--vt-c-black); --color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft); --color-background-soft: var(--vt-c-black-soft);
@@ -48,39 +48,4 @@
--color-heading: var(--vt-c-text-dark-1); --color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2); --color-text: var(--vt-c-text-dark-2);
} }
} } */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+10 -9
View File
@@ -1,35 +1,36 @@
@import './base.css'; @import './base.css';
#app { /* #app {
max-width: 1280px; max-width: 1280px;
margin: 0 auto; margin: 0 auto;
padding: 2rem; padding: 2rem;
font-weight: normal; font-weight: normal;
} } */
a, /* a,
.green { .green {
text-decoration: none; text-decoration: none;
color: hsla(160, 100%, 37%, 1); color: hsla(160, 100%, 37%, 1);
transition: 0.4s; transition: 0.4s;
padding: 3px; padding: 3px;
} } */
@media (hover: hover) { /* @media (hover: hover) {
a:hover { a:hover {
background-color: hsla(160, 100%, 37%, 0.2); background-color: hsla(160, 100%, 37%, 0.2);
} }
} } */
@media (min-width: 1024px) { /* @media (min-width: 1024px) {
body { body {
display: flex; display: flex;
place-items: center; place-items: center;
} }
#app { #app {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
padding: 0 2rem; padding: 0 2rem;
} }
}
} */
+75
View File
@@ -0,0 +1,75 @@
<script setup lang="ts">
import { RouterLink } from 'vue-router'
</script>
<template>
<ul>
<li><RouterLink to="/">Home</RouterLink></li>
<li><RouterLink to="/comics">Comics</RouterLink></li>
<li><RouterLink to="/tysc">TYSC</RouterLink></li>
<li><RouterLink to="/mediq">Media</RouterLink></li>
<li style="float: right"><RouterLink to="/about">About</RouterLink></li>
</ul>
</template>
<style lang="css" scoped>
nav {
width: 100%;
font-size: 12px;
text-align: left;
margin-top: 2rem;
}
nav a.router-link-exact-active {
color: var(--color-text);
}
nav a.router-link-exact-active:hover {
background-color: transparent;
}
nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}
nav a:first-of-type {
border: 0;
}
ul {
position: sticky;
width: 90%;
align-items: center;
top: 0;
list-style-type: none;
margin: 1em;
padding: 1em;
overflow: hidden;
background-color: lightgray;
border-radius: 10px;
}
li {
float: left;
border-right: 1px solid #bbb;
}
li:last-child {
border-right: none;
}
li a {
display: block;
color: darkblue;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover:not(.active) {
background-color: gray;
}
.active {
background-color: #04aa6d;
}
</style>
+6
View File
@@ -1,5 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue' import HomeView from '../views/HomeView.vue'
import ComicsView from '@/views/ComicsView.vue'
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
@@ -9,6 +10,11 @@ const router = createRouter({
name: 'home', name: 'home',
component: HomeView, component: HomeView,
}, },
{
path: '/comics',
name: 'comics',
component: ComicsView,
},
{ {
path: '/about', path: '/about',
name: 'about', name: 'about',
+6
View File
@@ -0,0 +1,6 @@
<script setup lang="ts"></script>
<template>
<div>
<h2>Comics</h2>
</div>
</template>