Compare commits
6 Commits
9c90710bf3
...
last_habit
Author | SHA1 | Date | |
---|---|---|---|
eff5be49c4 | |||
d13c490efb | |||
d98c208df9 | |||
85af85b1ee | |||
1ff7fc454f | |||
e0dfc7120f |
@@ -40,7 +40,7 @@ define('DB_NAME', 'your db name');
|
|||||||
3. Start an local web server
|
3. Start an local web server
|
||||||
- You can use php's integrated server by running this:
|
- You can use php's integrated server by running this:
|
||||||
```bash
|
```bash
|
||||||
php -S localhost:8000
|
php -S localhost:8000 -t ./public
|
||||||
```
|
```
|
||||||
- You can use any host and any port you want.
|
- You can use any host and any port you want.
|
||||||
|
|
||||||
|
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
<section class="dashboard">
|
<section class="dashboard">
|
||||||
<h1>Welcome, <?= htmlspecialchars($_SESSION['user']['username']) ?>!</h1>
|
<h1>Welcome, <?= htmlspecialchars($_SESSION['user']['username']) ?>!</h1>
|
||||||
<a href="/habits/create" class="btn-primary">Create new habit!</a>
|
<div>
|
||||||
|
<a href="/habits/create" class="btn-green">Create new habit!</a>
|
||||||
|
<a href="/habits" class="btn-primary">List all habits</a>
|
||||||
|
</div>
|
||||||
<div class="card-wrapper">
|
<div class="card-wrapper">
|
||||||
<section class="card upcoming">
|
<section class="card upcoming">
|
||||||
<h2>Upcoming</h2>
|
<h2>Upcoming</h2>
|
||||||
|
@@ -10,10 +10,10 @@
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<form method="POST" action="/habits/create">
|
<form method="POST" action="/habits/create">
|
||||||
<label for="name">Habit Name:</label>
|
<label for="name">Habit Name</label>
|
||||||
<input type="text" name="name" id="name" required value="<?= htmlspecialchars($_POST['name'] ?? '') ?>">
|
<input type="text" name="name" id="name" required value="<?= htmlspecialchars($_POST['name'] ?? '') ?>">
|
||||||
|
|
||||||
<label for="frequency">Frequency:</label>
|
<label for="frequency">Frequency</label>
|
||||||
<select name="frequency" id="frequency" onchange="toggleCustomFrequency(this.value)">
|
<select name="frequency" id="frequency" onchange="toggleCustomFrequency(this.value)">
|
||||||
<option value="Daily">Daily</option>
|
<option value="Daily">Daily</option>
|
||||||
<option value="Weekly">Weekly</option>
|
<option value="Weekly">Weekly</option>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div id="custom-frequency" style="display: none;">
|
<div id="custom-frequency" style="display: none;">
|
||||||
<label id="lbl_dow">Days of the Week:</label>
|
<label id="lbl_dow">Days of the Week</label>
|
||||||
<div class="dow_chb_wrapper">
|
<div class="dow_chb_wrapper">
|
||||||
<label for="dow_mon">Monday</label>
|
<label for="dow_mon">Monday</label>
|
||||||
<input type="checkbox" name="days_of_week[]" id="dow_mon" value="1">
|
<input type="checkbox" name="days_of_week[]" id="dow_mon" value="1">
|
||||||
@@ -51,10 +51,10 @@
|
|||||||
<input type="checkbox" name="days_of_week[]" id="dow_sun" value="7">
|
<input type="checkbox" name="days_of_week[]" id="dow_sun" value="7">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="days_of_month" id="lbl_dom">Days of the Month:</label>
|
<label for="days_of_month" id="lbl_dom">Days of the Month</label>
|
||||||
<input type="text" name="days_of_month" id="days_of_month" placeholder="1,15 (comma-separated)">
|
<input type="text" name="days_of_month" id="days_of_month" placeholder="1,15 (comma-separated)">
|
||||||
|
|
||||||
<label for="months">Months:</label>
|
<label for="months">Months</label>
|
||||||
<input type="text" name="months" id="months" placeholder="1,7,12 (comma-separated)">
|
<input type="text" name="months" id="months" placeholder="1,7,12 (comma-separated)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -3,33 +3,22 @@
|
|||||||
<?php if (empty($this->get('habits'))): ?>
|
<?php if (empty($this->get('habits'))): ?>
|
||||||
<p>No habits yet. <a href="/habits/create">Create your first habit</a>.</p>
|
<p>No habits yet. <a href="/habits/create">Create your first habit</a>.</p>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<table>
|
<div class="habits-wrapper">
|
||||||
<thead>
|
<?php foreach ($this->get('habits') as $habit): ?>
|
||||||
<tr>
|
<div class="habit bordered">
|
||||||
<th>Title</th>
|
<b><?= htmlspecialchars($habit['title']) ?></b>
|
||||||
<th>Frequency</th>
|
<p>Frequency: <?= htmlspecialchars($habit['frequency']) ?></p>
|
||||||
<th>Custom Schedule</th>
|
<?php if (isset($habit['custom_frequency'])): ?>
|
||||||
<th>Points</th>
|
<p><?= htmlspecialchars($habit['custom_frequency'] ?? 'N/A') ?></p>
|
||||||
<th>Created At</th>
|
<?php endif; ?>
|
||||||
<th>Actions</th>
|
<p><?= htmlspecialchars($habit['reward_points']) ?></p>
|
||||||
</tr>
|
<p><?= htmlspecialchars($habit['created_at']) ?></p>
|
||||||
</thead>
|
<a href="/habits/done">Mark as done</a> |
|
||||||
<tbody>
|
<a href="/habits/edit?id=<?= $habit['id'] ?>">Edit</a> |
|
||||||
<?php foreach ($this->get('habits') as $habit): ?>
|
<a href="/habits/delete?id=<?= $habit['id'] ?>" onclick="return confirm('Are you sure you want to delete this habit?')">Delete</a>
|
||||||
<tr>
|
</div>
|
||||||
<td><?= htmlspecialchars($habit['title']) ?></td>
|
<?php endforeach; ?>
|
||||||
<td><?= htmlspecialchars($habit['frequency']) ?></td>
|
</div>
|
||||||
<td><?= htmlspecialchars($habit['custom_frequency'] ?? 'N/A') ?></td>
|
<a href="/habits/create" class="btn-green">Create new habit!</a>
|
||||||
<td><?= htmlspecialchars($habit['reward_points']) ?></td>
|
|
||||||
<td><?= htmlspecialchars($habit['created_at']) ?></td>
|
|
||||||
<td>
|
|
||||||
<a href="/habits/edit?id=<?= $habit['id'] ?>">Edit</a> |
|
|
||||||
<a href="/habits/delete?id=<?= $habit['id'] ?>" onclick="return confirm('Are you sure you want to delete this habit?')">Delete</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<a href="/habits/create">Create new habit!</a>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</section>
|
</section>
|
||||||
|
@@ -17,14 +17,14 @@
|
|||||||
<header>
|
<header>
|
||||||
<div id="hd-left">
|
<div id="hd-left">
|
||||||
<a href="/"><img src="/img/logo.jpg" alt="home"></a>
|
<a href="/"><img src="/img/logo.jpg" alt="home"></a>
|
||||||
<a href="/"><?= $data['title'] ?></a>
|
<label><?= $data['title'] ?></label>
|
||||||
</div>
|
</div>
|
||||||
<div id="hd-right">
|
<div id="hd-right">
|
||||||
<?php if (!isset($_SESSION['user'])): ?>
|
<?php if (!isset($_SESSION['user'])): ?>
|
||||||
<a href="/auth/signin">Log In</a>
|
<a href="/auth/signin">Log In</a>
|
||||||
<a href="/auth/signup">Sign Up</a>
|
<a href="/auth/signup">Sign Up</a>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="/auth/logout">Log Out</a>
|
<a href="/auth/logout" class="btn-secondary">Sign out</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
mariadb:
|
mariadb:
|
||||||
image: mariadb:11.4 # LTS at 25. 12. 2025
|
image: mariadb:11.4 # LTS at 25. 12. 2025
|
||||||
restart: always
|
restart: on-failure:2
|
||||||
environment:
|
environment:
|
||||||
MARIADB_ROOT_PASSWORD: root
|
MARIADB_ROOT_PASSWORD: root
|
||||||
ports:
|
ports:
|
||||||
@@ -10,7 +10,7 @@ services:
|
|||||||
|
|
||||||
phpmyadmin:
|
phpmyadmin:
|
||||||
image: phpmyadmin
|
image: phpmyadmin
|
||||||
restart: always
|
restart: on-failure:2
|
||||||
ports:
|
ports:
|
||||||
- 8080:80
|
- 8080:80
|
||||||
environment:
|
environment:
|
||||||
@@ -21,10 +21,11 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
#volumes:
|
volumes:
|
||||||
# - .:/var/www/html
|
- .:/var/www/html
|
||||||
ports:
|
ports:
|
||||||
- 8000:80
|
- 8000:80
|
||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
|
restart: on-failure:2
|
||||||
profiles: ["prod"]
|
profiles: ["prod"]
|
||||||
|
@@ -1,32 +1,47 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap");
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Open Sans", serif;
|
font-family: "Open Sans", serif;
|
||||||
background-color: var(--clr-primary);
|
background-color: var(--clr-primary);
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary,
|
.btn-primary,
|
||||||
|
.btn-secondary,
|
||||||
|
.btn-tertiary,
|
||||||
|
.btn-green,
|
||||||
.btn-danger {
|
.btn-danger {
|
||||||
background-color: var(--clr-green);
|
background-color: var(--clr-primary);
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: var(--border-radious);
|
border-radius: var(--border-radious);
|
||||||
border: var(--borderWidth-thin) solid var(--clr-border);
|
border: var(--borderWidth-thin) solid var(--clr-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: var(--clr-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-tertiary {
|
||||||
|
background-color: var(--clr-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-green {
|
||||||
|
background-color: var(--clr-green);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-danger {
|
.btn-danger {
|
||||||
background-color: var(--clr-danger-muted) !important;
|
background-color: var(--clr-danger-muted);
|
||||||
border: var(--borderWidth-thin) solid var(--clr-border-danger);
|
border: var(--borderWidth-thin) solid var(--clr-border-danger);
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,15 @@
|
|||||||
.habits h1 {
|
.habits-wrapper {
|
||||||
font-size: 2rem;
|
display: flex;
|
||||||
margin-bottom: 1rem;
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.habits table {
|
.habits .bordered {
|
||||||
width: 100%;
|
border-radius: var(--border-radious);
|
||||||
border-collapse: collapse;
|
border: var(--borderWidth-thin) solid var(--clr-border);
|
||||||
|
width: 17rem;
|
||||||
|
padding: 1rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
text-align: center;
|
||||||
|
|
||||||
.habits table th,
|
|
||||||
.habits table td {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 8px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.habits a {
|
|
||||||
color: #007bff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.habits a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,11 @@
|
|||||||
--clr-danger-muted: #f851491a;
|
--clr-danger-muted: #f851491a;
|
||||||
|
|
||||||
--clr-link-blue: #4493f8;
|
--clr-link-blue: #4493f8;
|
||||||
|
--clr-light-blue: #39a2ae;
|
||||||
|
--clr-light-green: #71f79f;
|
||||||
|
--clr-red: #9b1d20;
|
||||||
|
--clr-orange: #e08e45;
|
||||||
|
--clr-gray-blue: #627c85;
|
||||||
|
|
||||||
--border-radious: 5px;
|
--border-radious: 5px;
|
||||||
--borderWidth-thin: max(1px, 0.0625rem);
|
--borderWidth-thin: max(1px, 0.0625rem);
|
||||||
|
Reference in New Issue
Block a user