Combine add product to wishlists
This commit is contained in:
parent
4ba3797bc5
commit
b1581d907c
8 changed files with 293 additions and 210 deletions
|
@ -17,16 +17,9 @@ require '../../index.php';
|
|||
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'GET':
|
||||
$cache = new EmbedCache($_GET['url']);
|
||||
$cache = new EmbedCache($_GET['product_url']);
|
||||
$info = $cache->get(true);
|
||||
|
||||
if ($info->url && str_contains($_GET['url'], $info->url)) {
|
||||
$database->query('UPDATE `products`
|
||||
SET `url` = "' . $info->url . '"
|
||||
WHERE `id` = ' . $_GET['product_id'] . '
|
||||
;');
|
||||
}
|
||||
|
||||
$response['success'] = true;
|
||||
$response['data'] = $info;
|
||||
break;
|
||||
|
|
|
@ -16,24 +16,18 @@ $response = array(
|
|||
require '../../index.php';
|
||||
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'PUT':
|
||||
parse_str(file_get_contents("php://input"), $_PUT);
|
||||
|
||||
if (isset($_PUT['productID'], $_PUT['productStatus'])) {
|
||||
$database->query('UPDATE `products`
|
||||
SET `status` = "' . $_PUT['productStatus'] . '"
|
||||
WHERE `id` = ' . $_PUT['productID'] . '
|
||||
;');
|
||||
|
||||
$response['success'] = true;
|
||||
} elseif (isset($_PUT['wishlist_id'], $_PUT['url'])) {
|
||||
case 'POST':
|
||||
if (isset($_POST['wishlist_id'], $_POST['product_url'])) {
|
||||
/**
|
||||
* Insert New Product
|
||||
*/
|
||||
$database->query('INSERT INTO `products`
|
||||
(
|
||||
`wishlist`,
|
||||
`url`
|
||||
`wishlist`,
|
||||
`url`
|
||||
) VALUES ('
|
||||
. $_PUT['wishlist_id'] . ',
|
||||
"' . $_PUT['url'] . '"
|
||||
. $_POST['wishlist_id'] . ',
|
||||
"' . $_POST['product_url'] . '"
|
||||
)
|
||||
;');
|
||||
|
||||
|
@ -44,6 +38,32 @@ switch ($_SERVER['REQUEST_METHOD']) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
parse_str(file_get_contents("php://input"), $_PUT);
|
||||
|
||||
if (isset($_PUT['productID'], $_PUT['productStatus'])) {
|
||||
/**
|
||||
* Update Product Status
|
||||
*/
|
||||
$database->query('UPDATE `products`
|
||||
SET `status` = "' . $_PUT['productStatus'] . '"
|
||||
WHERE `id` = ' . $_PUT['productID'] . '
|
||||
;');
|
||||
|
||||
$response['success'] = true;
|
||||
} elseif (isset($_PUT['product_url_current'], $_PUT['product_url_proposed'])) {
|
||||
/**
|
||||
* Update Product URL
|
||||
*/
|
||||
$database->query('UPDATE `products`
|
||||
SET `url` = "' . $_PUT['product_url_proposed'] . '"
|
||||
WHERE `url` = "' . $_PUT['product_url_current'] . '"
|
||||
;');
|
||||
|
||||
$response['success'] = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DELETE':
|
||||
parse_str(file_get_contents("php://input"), $_DELETE);
|
||||
|
||||
|
|
|
@ -95,50 +95,4 @@ $(function() {
|
|||
.modal('show');
|
||||
}
|
||||
/** */
|
||||
|
||||
$('.ui.dropdown.wishlists').dropdown({
|
||||
filterRemoteData: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Product
|
||||
*/
|
||||
$(document).on('click', '.ui.button.delete', function() {
|
||||
var button = $(this);
|
||||
var card = button.closest('.ui.card');
|
||||
var column = card.closest('.column');
|
||||
|
||||
$('body')
|
||||
.modal({
|
||||
title: 'Really delete?',
|
||||
content: 'Would you really like to delete to this product? It will be gone forever.',
|
||||
class: 'tiny',
|
||||
actions: [
|
||||
{
|
||||
text: 'Yes, delete',
|
||||
class: 'approve primary'
|
||||
},
|
||||
{
|
||||
text: 'Cancel'
|
||||
}
|
||||
],
|
||||
onApprove: function() {
|
||||
/**
|
||||
* Delete product
|
||||
*/
|
||||
button.api({
|
||||
action: 'delete product',
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
productID: card.data('id'),
|
||||
},
|
||||
on: 'now',
|
||||
onSuccess: function() {
|
||||
column.fadeOut();
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.modal('show');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
$(function() {
|
||||
$('.ui.dropdown.wishlists').api({
|
||||
action: 'get wishlists',
|
||||
method: 'GET',
|
||||
on: 'now'
|
||||
});
|
||||
|
||||
$(document).on('submit', '.ui.form', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var form = $(event.currentTarget);
|
||||
var card = $('.ui.card');
|
||||
|
||||
var url = $('.ui.form [name="url"]').val();
|
||||
|
||||
card.find('.content a').attr('href', url);
|
||||
|
||||
fetch('/src/api/products.php', {
|
||||
method: 'PUT',
|
||||
body: form.serialize()
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
card.attr('data-id', response.data.lastInsertId);
|
||||
card.attr('data-cache', 'false');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,14 +1,14 @@
|
|||
$(function() {
|
||||
$(function () {
|
||||
/**
|
||||
* Get Wishlists
|
||||
*/
|
||||
var wishlists = [];
|
||||
|
||||
$('.ui.dropdown.wishlists').api({
|
||||
action: 'get wishlists',
|
||||
method: 'GET',
|
||||
on: 'now',
|
||||
onSuccess: function(response, element, xhr) {
|
||||
action: 'get wishlists',
|
||||
method: 'GET',
|
||||
on: 'now',
|
||||
onSuccess: function (response, element, xhr) {
|
||||
wishlists = response.results;
|
||||
|
||||
element.dropdown({
|
||||
|
@ -29,7 +29,7 @@ $(function() {
|
|||
/**
|
||||
* Selection
|
||||
*/
|
||||
$(document).on('change', '.ui.dropdown.wishlists', function() {
|
||||
$(document).on('change', '.ui.dropdown.wishlists', function () {
|
||||
var wishlistValue = $('.ui.dropdown.wishlists').dropdown('get value');
|
||||
var wishlistIndex = $('.ui.dropdown.wishlists select').prop('selectedIndex') - 1;
|
||||
|
||||
|
@ -41,9 +41,11 @@ $(function() {
|
|||
|
||||
$('.wishlist-share').attr('href', '/?wishlist=' + wishlists[wishlistIndex].hash);
|
||||
|
||||
$('.wishlist-product-add').removeClass('disabled');
|
||||
$('.wishlist-share').removeClass('disabled');
|
||||
$('.wishlist-delete button').removeClass('disabled');
|
||||
} else {
|
||||
$('.wishlist-product-add').addClass('disabled');
|
||||
$('.wishlist-share').addClass('disabled');
|
||||
$('.wishlist-delete button').addClass('disabled');
|
||||
}
|
||||
|
@ -57,11 +59,11 @@ $(function() {
|
|||
* Generate cache
|
||||
*/
|
||||
var timerInterval = 1200;
|
||||
var timerCache = setTimeout(
|
||||
var timerCache = setTimeout(
|
||||
function generateCacheCards() {
|
||||
var cards = $('.ui.card[data-cache="false"]');
|
||||
|
||||
cards.each(function(index, card) {
|
||||
cards.each(function (index, card) {
|
||||
generateCacheCard(card);
|
||||
|
||||
if (index >= 0) {
|
||||
|
@ -80,14 +82,14 @@ $(function() {
|
|||
function generateCacheCard(card) {
|
||||
card = $(card);
|
||||
|
||||
var href = card.find('.content [href]').prop('href');
|
||||
var href = card.find('.content [href]').prop('href');
|
||||
var product_id = card.data('id');
|
||||
var refresh = card.find('button.refresh');
|
||||
var refresh = card.find('button.refresh');
|
||||
|
||||
card.addClass('loading');
|
||||
card.attr('data-cache', true);
|
||||
|
||||
fetch('/src/api/cache.php?product_id=' + product_id + '&url=' + href, {
|
||||
fetch('/src/api/cache.php?product_id=' + product_id + '&product_url=' + href, {
|
||||
method: 'GET'
|
||||
})
|
||||
.then(response => response.json())
|
||||
|
@ -98,7 +100,7 @@ $(function() {
|
|||
/**
|
||||
* Elements
|
||||
*/
|
||||
var elementImage = card.children('.image');
|
||||
var elementImage = card.children('.image');
|
||||
var elementContent = card.children('.content').first();
|
||||
var elementDetails = card.children('.extra.content.details');
|
||||
var elementButtons = card.children('.extra.content.buttons');
|
||||
|
@ -110,7 +112,7 @@ $(function() {
|
|||
if (!elementImage.length) {
|
||||
card.prepend(
|
||||
'<div class="image">' +
|
||||
'<img class="preview" src="' + info.image + '" loading="lazy">' +
|
||||
'<img class="preview" src="' + info.image + '" loading="lazy">' +
|
||||
'</div>'
|
||||
);
|
||||
} else {
|
||||
|
@ -145,7 +147,7 @@ $(function() {
|
|||
/**
|
||||
* Header
|
||||
*/
|
||||
var elementContentHeader = elementContent.children('.header');
|
||||
var elementContentHeader = elementContent.children('.header');
|
||||
var elementContentHeaderTitle = elementContentHeader.children('a');
|
||||
|
||||
/** Title */
|
||||
|
@ -192,9 +194,9 @@ $(function() {
|
|||
/**
|
||||
* Refresh
|
||||
*/
|
||||
$(document).on('click', '.ui.button.refresh', function(event) {
|
||||
$(document).on('click', '.ui.button.refresh', function (event) {
|
||||
var button = $(event.currentTarget);
|
||||
var card = button.closest('.ui.card');
|
||||
var card = button.closest('.ui.card');
|
||||
|
||||
button.addClass('working');
|
||||
|
||||
|
@ -204,7 +206,7 @@ $(function() {
|
|||
/**
|
||||
* Delete Wishlist
|
||||
*/
|
||||
$(document).on('submit', '.wishlist-delete', function(event) {
|
||||
$(document).on('submit', '.wishlist-delete', function (event) {
|
||||
var wishlistValue = $('.ui.dropdown.wishlists').dropdown('get value');
|
||||
|
||||
if (wishlistValue) {
|
||||
|
@ -223,15 +225,15 @@ $(function() {
|
|||
class: 'deny'
|
||||
},
|
||||
],
|
||||
onApprove: function() {
|
||||
onApprove: function () {
|
||||
$('.ui.dropdown.wishlists').api({
|
||||
action: 'delete wishlist',
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
data: {
|
||||
wishlistID: wishlistValue
|
||||
},
|
||||
on: 'now',
|
||||
onSuccess: function(response, wishlists) {
|
||||
on: 'now',
|
||||
onSuccess: function (response, wishlists) {
|
||||
$('.wishlist-cards .column').fadeOut();
|
||||
|
||||
wishlists.dropdown('clear');
|
||||
|
@ -242,7 +244,7 @@ $(function() {
|
|||
$('.ui.dropdown.wishlists').api({
|
||||
action: 'get wishlists',
|
||||
method: 'GET',
|
||||
on: 'now'
|
||||
on: 'now'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -253,4 +255,164 @@ $(function() {
|
|||
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Product
|
||||
*/
|
||||
$(document).on('click', '.ui.button.delete', function () {
|
||||
var button = $(this);
|
||||
var card = button.closest('.ui.card');
|
||||
var column = card.closest('.column');
|
||||
|
||||
$('body')
|
||||
.modal({
|
||||
title: 'Really delete?',
|
||||
content: 'Would you really like to delete to this product? It will be gone forever.',
|
||||
class: 'tiny',
|
||||
actions: [
|
||||
{
|
||||
text: 'Yes, delete',
|
||||
class: 'approve primary'
|
||||
},
|
||||
{
|
||||
text: 'Cancel'
|
||||
}
|
||||
],
|
||||
onApprove: function () {
|
||||
/**
|
||||
* Delete product
|
||||
*/
|
||||
button.api({
|
||||
action: 'delete product',
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
productID: card.data('id'),
|
||||
},
|
||||
on: 'now',
|
||||
onSuccess: function () {
|
||||
column.fadeOut();
|
||||
|
||||
location.href = '/?page=wishlists';
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.modal('show');
|
||||
});
|
||||
|
||||
/**
|
||||
* Add product
|
||||
*/
|
||||
$(document).on('click', '.wishlist-product-add', function () {
|
||||
var modal = $('.ui.modal.wishlist-product-add');
|
||||
|
||||
modal.find('[name="wishlist_id"]').val($('.ui.dropdown.wishlists').dropdown('get value'));
|
||||
modal
|
||||
.modal({
|
||||
onApprove: function (button) {
|
||||
button.addClass('loading');
|
||||
|
||||
var form = $('.ui.form.wishlist-product-fetch');
|
||||
var formData = new URLSearchParams();
|
||||
formData.append('wishlist_id', form.find('input[name="wishlist_id"]').val());
|
||||
formData.append('product_url', form.find('input[name="product_url"]').val());
|
||||
|
||||
fetch('/src/api/products.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
modal.modal('hide');
|
||||
}
|
||||
|
||||
button.removeClass('loading');
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
onDeny: function (element) {
|
||||
return false;
|
||||
},
|
||||
})
|
||||
.modal('show');
|
||||
});
|
||||
|
||||
/** Fetch */
|
||||
$(document).on('submit', '.wishlist-product-fetch', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var form = $(event.currentTarget);
|
||||
var href = form.find('[name="product_url"]').val();
|
||||
|
||||
var elementModalAdd = $('.ui.modal.wishlist-product-add');
|
||||
var elementButtons = elementModalAdd.find('.actions .button');
|
||||
var elementImage = elementModalAdd.find('.image img');
|
||||
|
||||
form.addClass('loading');
|
||||
elementButtons.addClass('disabled');
|
||||
|
||||
fetch('/src/api/cache.php?product_url=' + href, {
|
||||
method: 'GET'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
var info = response.data;
|
||||
|
||||
/**
|
||||
* Image
|
||||
*/
|
||||
if (info.image && elementImage.length) {
|
||||
elementImage.attr('src', info.image);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
if (info.url && info.url !== href) {
|
||||
var elementModalFetch = $('.ui.modal.wishlist-product-fetch');
|
||||
|
||||
elementModalFetch.find('input.current').val(href);
|
||||
elementModalFetch.find('input.proposed').val(info.url);
|
||||
|
||||
elementModalFetch
|
||||
.modal({
|
||||
allowMultiple: true,
|
||||
closable: false,
|
||||
onApprove: function (button) {
|
||||
var formData = new URLSearchParams();
|
||||
formData.append('product_url_current', href);
|
||||
formData.append('product_url_proposed', info.url);
|
||||
|
||||
button.addClass('loading');
|
||||
|
||||
fetch('/src/api/products.php', {
|
||||
method: 'PUT',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
form.find('input[type="url"]').val(info.url);
|
||||
|
||||
elementModalFetch.modal('hide');
|
||||
}
|
||||
|
||||
button.removeClass('loading');
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.modal('show');
|
||||
}
|
||||
}
|
||||
|
||||
form.removeClass('loading');
|
||||
elementButtons.removeClass('disabled');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -78,6 +78,7 @@ class Wishlist
|
|||
* Cards
|
||||
*/
|
||||
$userIsCurrent = isset($_SESSION['user']) && $this->data['user'] === $_SESSION['user']['id'];
|
||||
$cardIndex = 0;
|
||||
|
||||
if (!empty($products)) { ?>
|
||||
<div class="ui container">
|
||||
|
@ -88,7 +89,7 @@ class Wishlist
|
|||
$exists = $cache->exists() ? 'true' : 'false';
|
||||
?>
|
||||
<div class="column">
|
||||
<div class="ui fluid card stretch" data-id="<?= $product['id'] ?>" data-cache="<?= $exists ?>">
|
||||
<div class="ui fluid card stretch" data-id="<?= $product['id'] ?>" data-index="<?= $cardIndex ?>" data-cache="<?= $exists ?>">
|
||||
|
||||
<?php if ($info->image) { ?>
|
||||
<div class="image">
|
||||
|
@ -162,6 +163,8 @@ class Wishlist
|
|||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<? $cardIndex++ ?>
|
||||
<?php } else { ?>
|
||||
<div class="ui container">
|
||||
<div class="sixteen wide column">
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Add product to a wishlist.
|
||||
*
|
||||
* @author Jay Trees <github.jay@grandel.anonaddy.me>
|
||||
*/
|
||||
|
||||
use wishthis\{Page, User};
|
||||
|
||||
if (isset($_POST['url'], $_POST['wishlist'])) {
|
||||
$database->query('INSERT INTO `products`
|
||||
(`wishlist`, `url`) VALUES
|
||||
(' . $_POST['wishlist'] . ', "' . $_POST['url'] . '")
|
||||
;');
|
||||
}
|
||||
|
||||
$page = new page(__FILE__, 'Add a product');
|
||||
$page->header();
|
||||
$page->navigation();
|
||||
?>
|
||||
<main>
|
||||
<div class="ui container">
|
||||
<h1 class="ui header"><?= $page->title ?></h1>
|
||||
|
||||
<div class="ui grid">
|
||||
|
||||
<div class="eleven wide column">
|
||||
<div class="ui segment">
|
||||
<form class="ui form" method="post">
|
||||
<div class="field">
|
||||
<label>URL</label>
|
||||
<input type="url" name="url" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Wishlist</label>
|
||||
<select class="ui search selection dropdown loading wishlists" name="wishlist_id">
|
||||
<option value="">Loading your wishlists...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input class="ui primary button" type="submit" value="Add" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="five wide column">
|
||||
<div class="ui fitted segment">
|
||||
|
||||
<div class="ui fluid card">
|
||||
<div class="image">
|
||||
<img class="preview" src="/src/assets/img/no-image.svg" loading="lazy" />
|
||||
|
||||
<button class="ui icon button refresh">
|
||||
<i class="refresh icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
<a>Title</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="extra content buttons">
|
||||
<a class="ui small right labeled icon button disabled" target="_blank">
|
||||
<i class="external icon"></i>
|
||||
View
|
||||
</a>
|
||||
|
||||
<a class="ui small labeled red icon button disabled">
|
||||
<i class="trash icon"></i>
|
||||
Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
$page->footer();
|
|
@ -28,7 +28,7 @@ if (isset($_POST['wishlist-create'], $_POST['name'])) {
|
|||
)
|
||||
;');
|
||||
|
||||
header('Location: /?page=wishlist-product-add');
|
||||
header('Location: /?page=wishlists');
|
||||
die();
|
||||
}
|
||||
|
||||
|
@ -94,9 +94,9 @@ if (isset($_POST['wishlist_delete_id'])) {
|
|||
<h2 class="ui header">Options</h1>
|
||||
<p>Wishlist related options.</p>
|
||||
|
||||
<a class="ui small labeled icon button wishlist-product-add" href="/?page=wishlist-product-add">
|
||||
<a class="ui small labeled icon button wishlist-product-add disabled">
|
||||
<i class="add icon"></i>
|
||||
Add products
|
||||
Add a product
|
||||
</a>
|
||||
|
||||
<a class="ui small labeled icon button wishlist-share disabled" target="_blank">
|
||||
|
@ -118,5 +118,71 @@ if (isset($_POST['wishlist_delete_id'])) {
|
|||
<div class="wishlist-cards"></div>
|
||||
</main>
|
||||
|
||||
<div class="ui modal wishlist-product-add">
|
||||
<div class="header">
|
||||
Add a product
|
||||
</div>
|
||||
<div class="image content">
|
||||
<div class="ui medium image">
|
||||
<img src="/src/assets/img/no-image.svg" loading="lazy" />
|
||||
</div>
|
||||
<div class="description">
|
||||
<div class="ui header">Product</div>
|
||||
<p>Fill out the below fields to add your new product.</p>
|
||||
|
||||
<form class="ui form wishlist-product-fetch" method="post">
|
||||
<input type="hidden" name="wishlist_id" />
|
||||
|
||||
<div class="field">
|
||||
<label>URL</label>
|
||||
<input type="url" name="product_url" />
|
||||
</div>
|
||||
|
||||
<input class="ui button" type="submit" value="Fetch" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui primary approve button">
|
||||
Add
|
||||
</div>
|
||||
<div class="ui deny button">
|
||||
Cancel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small modal wishlist-product-fetch">
|
||||
<div class="header">
|
||||
Incorrect URL
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="description">
|
||||
<div class="ui header">Product URLs</div>
|
||||
<p>The URL you have entered does not seem quite right. Would you like to update it with the one I found?</p>
|
||||
|
||||
<div class="ui form urls">
|
||||
<div class="field">
|
||||
<label>Current</label>
|
||||
<input class="current" type="url" readonly />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Proposed</label>
|
||||
<input class="proposed" type="url" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui primary approve button">
|
||||
Yes, update
|
||||
</div>
|
||||
<div class="ui deny button">
|
||||
No, leave it
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$page->footer();
|
||||
|
|
Loading…
Reference in a new issue