Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Juan Montilla
/
TBW2223_equipo12
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
0a9b0608
authored
May 07, 2023
by
Juan Montilla
Committed by
Manuel Ruiz Toribio
May 09, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
ajax
parent
83dd03bb
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
540 additions
and
352 deletions
app/Config/Routes.php
app/Controllers/RecipesController.php
app/Models/RecipesModel.php
app/Views/pages/home.php
app/Views/pages/insertRecipe.php
app/Views/pages/recipe_view.php
app/Views/templates/header.php
public/css/style.css
public/imagenes/2729270.png
public/js/insert.js
public/js/main.js
app/Config/Routes.php
View file @
0a9b0608
...
...
@@ -38,6 +38,8 @@ $routes->match(['get', 'post'], '/registerAjax', [User::class, 'registerAjax']);
$routes
->
match
([
'get'
],
'/home'
,
[
User
::
class
,
'user_ok'
]);
$routes
->
get
(
'/recipe/(:num)'
,
'RecipesController::view_recipe/$1'
);
// Ruta para obtener una imagen de una receta dado un id
$routes
->
get
(
'recipe/image/(:num)'
,
'RecipesController::show_image/$1'
);
...
...
@@ -46,15 +48,19 @@ $routes->get('/insert_recipe', 'InsertRecipeController::index');
$routes
->
match
([
'get'
,
'post'
],
'/search_ingredient'
,
'InsertRecipeController::search_ingredient'
);
$routes
->
post
(
'/insert_recipe'
,
'InsertRecipeController::insert_recipe'
);
// Ruta para la búsqueda de recetas
$routes
->
match
([
'get'
,
'post'
],
'/search_recipe'
,
'RecipesController::search_recipe'
);
$routes
->
post
(
'filter_recipes'
,
'RecipesController::get_filtered_recipes'
);
$routes
->
get
(
'login'
,
'Pages::viewLogin'
);
$routes
->
get
(
'users'
,
'User::list'
);
$routes
->
get
(
'home'
,
'Pages::prueba'
);
$routes
->
get
(
'(:segment)'
,
'Home::index'
);
$routes
->
get
(
'/recipe/(:num)'
,
'RecipesController::view_recipe/$1'
);
...
...
app/Controllers/RecipesController.php
View file @
0a9b0608
...
...
@@ -25,7 +25,7 @@ class RecipesController extends Controller
];
return
view
(
'templates/header'
,
$data
)
.
view
(
'pages/recipe_view'
,
$data
)
.
view
(
'pages/recipe_view'
)
.
view
(
'templates/footer'
);
}
...
...
@@ -45,25 +45,26 @@ class RecipesController extends Controller
}
}
//public function search_recipe() {
// Obtener la consulta de búsqueda desde el formulario
// $query = $this->request->getVar('query');
// Cargar el modelo de ingredientes (si no lo has hecho)
//$recipesModel = new \App\Models\RecipesModel();
// Buscar ingredientes en la base de datos que coincidan con la consulta
// $recipes = $recipesModel->search_recipe($query);
// Devolver los ingredientes coincidentes en formato JSON
// return $this->response->setJSON($recipes);
// }
public
function
search_recipe
()
{
$query
=
$this
->
request
->
getVar
(
'query'
);
$recipesModel
=
new
\App\Models\RecipesModel
();
$recipes
=
$recipesModel
->
search
_r
ecipe
(
$query
);
$recipes
=
$recipesModel
->
search
R
ecipe
(
$query
);
return
$this
->
response
->
setJSON
(
$recipes
);
}
// En tu controlador de recetas
public
function
get_filtered_recipes
()
{
$recipesModel
=
new
\App\Models\RecipesModel
();
$vegan
=
$this
->
request
->
getPost
(
'is_vegan'
)
==
"true"
?
true
:
false
;
$country
=
$this
->
request
->
getPost
(
'origin'
);
$season
=
$this
->
request
->
getPost
(
'season'
);
$filtered_recipes
=
$recipesModel
->
get_filtered_recipes
(
$vegan
,
$country
,
$season
);
return
$this
->
response
->
setJSON
(
$filtered_recipes
);
}
}
\ No newline at end of file
app/Models/RecipesModel.php
View file @
0a9b0608
...
...
@@ -3,7 +3,7 @@ namespace App\Models;
use
CodeIgniter\Model
;
class
r
ecipesModel
extends
Model
class
R
ecipesModel
extends
Model
{
protected
$table
=
'recipes'
;
protected
$primaryKey
=
'id'
;
...
...
@@ -11,7 +11,7 @@ class recipesModel extends Model
protected
$returnType
=
'object'
;
# 'object' or 'array'
protected
$useSoftDeletes
=
false
;
# true if you expect to recover data
# Fields that can be set during save, insert, or update methods
protected
$allowedFields
=
[
'id'
,
'name'
,
'season'
,
'origin'
,
'photo'
,
'is_vegan'
,
'description'
,
'instructions'
,
'link'
];
protected
$allowedFields
=
[
'id'
,
'name'
,
'season'
,
'origin'
,
'photo'
,
'is_vegan'
,
'description'
,
'instructions'
,
'link'
];
protected
$useTimestamps
=
false
;
# no timestamps on inserts and updates
# Do not use validations rules (for the time being...)
protected
$validationRules
=
[];
...
...
@@ -35,7 +35,8 @@ class recipesModel extends Model
return
$this
->
insert
(
$data
);
}
public
function
get_recipe_ingredients
(
$recipe_id
)
{
public
function
get_recipe_ingredients
(
$recipe_id
)
{
$builder
=
$this
->
db
->
table
(
'recipes_ingredient'
);
$builder
->
select
(
'ingredient.name, ingredient.icon, recipes_ingredient.amount'
);
$builder
->
join
(
'ingredient'
,
'recipes_ingredient.id_ingredient = ingredient.id'
);
...
...
@@ -44,20 +45,39 @@ class recipesModel extends Model
return
$query
->
getResult
();
}
/* public function search_recipe($query)
public
function
searchRecipe
(
$query
)
{
if
(
$query
)
{
// Seleccionar todas las columnas excepto 'photo'
$this
->
select
(
'id, name, season, origin, is_vegan, description, instructions, link'
);
return
$this
->
like
(
'name'
,
$query
)
->
findAll
();
}
return
[];
}
*/
}
public
function
search_recipe
(
$query
)
{
if
(
$query
)
{
return
$this
->
like
(
'name'
,
$query
)
->
findAll
();
public
function
get_filtered_recipes
(
$vegan
,
$country
,
$season
)
{
$builder
=
$this
->
db
->
table
(
'recipes'
);
if
(
$vegan
)
{
$builder
->
where
(
'is_vegan'
,
true
);
}
return
[];
if
(
!
empty
(
$country
))
{
$builder
->
where
(
'origin'
,
$country
);
}
if
(
!
empty
(
$season
))
{
$builder
->
where
(
'season'
,
$season
);
}
$query
=
$builder
->
get
();
return
$query
->
getResult
();
}
}
\ No newline at end of file
app/Views/pages/home.php
View file @
0a9b0608
<!-- ======= Sidebar ======= -->
<aside
id=
"sidebar"
class=
"sidebar"
>
<ul
class=
"sidebar-nav"
id=
"sidebar-nav"
>
<li
class=
"nav-item"
>
<a
class=
"nav-link "
href=
"index.html"
>
<i
class=
"bi bi-grid"
></i>
<span>
Recetas
</span>
</a>
</li>
<!-- End Dashboard Nav -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro Vegano
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"vegan-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxOne"
value=
"Order one"
>
<label
for=
"checkboxOne"
>
Recetas Veganas
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav2"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro 2
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav2"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"indian-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFour"
value=
"Order four"
>
<label
for=
"checkboxFour"
>
India
</label>
</li>
</ul>
<ul
class=
"french-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFive"
value=
"Order five"
>
<label
for=
"checkboxFive"
>
Francia
</label>
</li>
</ul>
<ul
class=
"chinese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSix"
value=
"Order six"
>
<label
for=
"checkboxSix"
>
China
</label>
</li>
</ul>
<ul
class=
"mexican-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSeven"
value=
"Order seven"
>
<label
for=
"checkboxSeven"
>
México
</label>
</li>
</ul>
<ul
class=
"spanish-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEight"
value=
"Order eigth"
>
<label
for=
"checkboxEight"
>
España
</label>
</li>
</ul>
<ul
class=
"japanese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxNine"
value=
"Order nine"
>
<label
for=
"checkboxNine"
>
Japón
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav3"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Estaciones
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav3"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"winter-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTen"
value=
"Order ten"
>
<label
for=
"checkboxTen"
>
Invierno
</label>
</li>
</ul>
<ul
class=
"spring-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEleven"
value=
"Order eleven"
>
<label
for=
"checkboxEleven"
>
Primavera
</label>
</li>
</ul>
<ul
class=
"summer-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTwelve"
value=
"Order twelve"
>
<label
for=
"checkboxTwelve"
>
Verano
</label>
</li>
</ul>
<ul
class=
"autumn-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkbox13"
value=
"Order 13"
>
<label
for=
"checkbox13"
>
Otoño
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/insert_recipe"
>
<i
class=
"bi bi-file-earmark"
></i>
<span>
Subir receta
</span>
</a>
</li>
<!-- End Profile Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"https://www.instagram.com/salvaperfectti/"
>
<i
class=
"bi bi-envelope"
></i>
<span>
Contacto
</span>
</a>
</li>
<!-- End Contact Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/login"
>
<i
class=
"bi bi-box-arrow-in-right"
></i>
<span>
Registro/Login
</span>
</a>
</li>
<!-- End Login Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"http://www.homerswebpage.com/"
>
<i
class=
"bi bi-dash-circle"
></i>
<span>
Error 404
</span>
</a>
</li>
<!-- End Error 404 Page Nav -->
</ul>
</aside>
<!-- End Sidebar-->
<main
id=
"main"
class=
"main"
>
<div
class=
"pagetitle"
>
<h1>
Recetas
</h1>
<nav>
...
...
@@ -169,8 +12,8 @@
</nav>
</div>
<!-- End Page Title -->
<section
class=
"section dashboard"
>
<section
class=
"section dashboard"
id=
"recipeSection"
>
<div
id=
"recipeCards"
>
<?php
$recipesModel
=
new
\App\Models\RecipesModel
();
$recipes
=
$recipesModel
->
findAll
();
...
...
@@ -179,18 +22,18 @@
foreach
(
$recipes
as
$row
)
{
$ingredients
=
$recipesModel
->
get_recipe_ingredients
(
$row
->
id
);
?>
<!-- Inicio de la tarjeta de la receta -->
<div
class=
"recipe-card-wrapper"
>
<a
href=
"
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
"
class=
"recipe-card-link"
>
<div
class=
"card info-card sales-card"
>
<div
class=
"row"
>
<div
class=
"col-md-3 imagen-container"
>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
"
alt=
""
class=
"img-fluid rounded-start"
>
<div
class=
"card info-card sales-card"
onclick=
"window.location.href='
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
'"
>
<a
href=
"
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
"
>
</a>
<div
class=
"row flex-nowrap"
>
<div
class=
"col-lg-3 col-md-4 col-sm-12 imagen-container"
>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
"
alt=
""
class=
"img-fluid rounded-start"
>
</div>
<div
class=
"col-md-9
"
>
<div
class=
"col-lg-9 col-md-8 col-sm-12
"
>
<div
class=
"filter"
>
<a
class=
"icon"
href=
"#"
data-bs-toggle=
"dropdown"
><i
class=
"bi bi-three-dots"
></i></a>
<ul
class=
"dropdown-menu dropdown-menu-end dropdown-menu-arrow"
>
...
...
@@ -222,16 +65,114 @@
</div>
</div>
</div>
</a>
</div>
<!-- Fin de la tarjeta de la receta -->
<?php
}
}
?>
</div>
</section>
</main>
<!-- End #main -->
</section>
<script>
function
updateRecipeList
()
{
// Obtén el estado de los checkboxes
var
vegan
=
document
.
getElementById
(
"checkboxOne"
).
checked
;
var
countries
=
[
'India'
,
'Francia'
,
'China'
,
'México'
,
'España'
,
'Japón'
];
var
country
=
''
;
</main>
<!-- End #main -->
\ No newline at end of file
var
checkboxes
=
document
.
querySelectorAll
(
'input[type=checkbox]'
);
for
(
var
i
=
0
;
i
<
checkboxes
.
length
;
i
++
)
{
if
(
checkboxes
[
i
].
checked
&&
countries
.
includes
(
checkboxes
[
i
].
nextElementSibling
.
innerText
))
{
country
=
checkboxes
[
i
].
nextElementSibling
.
innerText
;
break
;
}
}
var
seasons
=
[
'Invierno'
,
'Primavera'
,
'Verano'
,
'Otoño'
];
var
season
=
''
;
for
(
var
i
=
0
;
i
<
checkboxes
.
length
;
i
++
)
{
if
(
checkboxes
[
i
].
checked
&&
seasons
.
includes
(
checkboxes
[
i
].
nextElementSibling
.
innerText
))
{
season
=
checkboxes
[
i
].
nextElementSibling
.
innerText
;
break
;
}
}
// Enviar una solicitud AJAX a tu controlador de recetas
var
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
"POST"
,
"/filter_recipes"
,
true
);
xhr
.
setRequestHeader
(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
xhr
.
onreadystatechange
=
function
()
{
if
(
this
.
readyState
===
4
&&
this
.
status
===
200
)
{
// Actualizar el contenido de la página con las recetas filtradas
var
recipes
=
JSON
.
parse
(
this
.
responseText
);
var
recipeList
=
document
.
getElementById
(
"recipeCards"
);
recipeList
.
innerHTML
=
''
;
// Limpiar la lista de recetas
for
(
var
i
=
0
;
i
<
recipes
.
length
;
i
++
)
{
var
recipeHTML
=
generateRecipeHTML
(
recipes
[
i
]);
recipeList
.
innerHTML
+=
recipeHTML
;
}
}
};
xhr
.
send
(
"is_vegan="
+
vegan
+
"&origin="
+
country
+
"&season="
+
season
);
}
function
generateRecipeHTML
(
recipe
)
{
var
recipeHTML
=
`
<div class="card info-card sales-card"
onclick="window.location.href='
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
'">
<a href="
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
">
</a>
<div class="row flex-nowrap">
<div class="col-lg-3 col-md-4 col-sm-12 imagen-container">
<img src="
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
" alt=""
class="img-fluid rounded-start">
</div>
<div class="col-lg-9 col-md-8 col-sm-12">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Opciones</h6>
</li>
<li><a class="dropdown-item" href="#">Guardar</a></li>
<li><a class="dropdown-item" href="#">Compartir</a></li>
</ul>
</div>
<div class="card-body">
<h5 class="card-title">
<?php
echo
$row
->
name
;
?>
<span>|
<?php
echo
$row
->
origin
;
?>
</span>
</h5>
<!--ingredientes-->
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<div class="chip" title="Cantidad:
<?php
echo
$ingredient
->
amount
;
?>
">
<img src="imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
">
<b style="font-size: 14px">
<?php
echo
$ingredient
->
name
;
?>
</b>
</div>
<?php
}
?>
<!--fin ingredientes-->
</div>
</div>
</div>
</div>`
;
return
recipeHTML
;
}
document
.
addEventListener
(
'DOMContentLoaded'
,
(
event
)
=>
{
updateRecipeList
();
});
</script>
\ No newline at end of file
app/Views/pages/insertRecipe.php
View file @
0a9b0608
...
...
@@ -42,9 +42,8 @@
<select
id=
"origin"
name=
"origin"
class=
"form-control"
>
<option
value=
"Española"
>
Española
</option>
<option
value=
"Francesa"
>
Francesa
</option>
<option
value=
"Italiana"
>
Italian
a
</option>
<option
value=
"Italiana"
>
Japones
a
</option>
<option
value=
"Mexiana"
>
Mexicana
</option>
<option
value=
"Americana"
>
Americana
</option>
<option
value=
"China"
>
China
</option>
<option
value=
"India"
>
India
</option>
</select>
...
...
app/Views/pages/recipe_view.php
View file @
0a9b0608
<?php
function
getYoutubeVideoId
(
$url
)
{
function
getYoutubeVideoId
(
$url
)
{
$pattern
=
'/^(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i'
;
preg_match
(
$pattern
,
$url
,
$matches
);
return
isset
(
$matches
[
1
])
?
$matches
[
1
]
:
null
;
...
...
@@ -62,7 +63,8 @@ function getYoutubeVideoId($url) {
.video-container
{
position
:
relative
;
padding-bottom
:
56.25%
;
/* Relación de aspecto 16:9 */
padding-bottom
:
56.25%
;
/* Relación de aspecto 16:9 */
height
:
0
;
overflow
:
hidden
;
}
...
...
@@ -74,41 +76,52 @@ function getYoutubeVideoId($url) {
width
:
100%
;
height
:
100%
;
}
</style>
</style>
<main
id=
"mainview"
class=
"mainview"
>
<section
class=
"section dashboard"
>
<main
id=
"main"
class=
"main"
>
<section
class=
"section dashboard"
>
<div
class=
"container"
>
<div
class=
"recipe-header"
>
<h1>
Receta:
</h1>
<h1>
<?php
echo
$recipe
->
name
;
?>
</h1>
<h1>
<?php
echo
$recipe
->
name
;
?>
</h1>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$recipe
->
id
);
?>
"
alt=
"
<?php
echo
$recipe
->
name
;
?>
"
/>
</div>
<p>
<?php
echo
$recipe
->
description
;
?>
</p>
<p>
<?php
echo
$recipe
->
description
;
?>
</p>
<h2>
Ingredientes
</h2>
<ul
class=
"ingredient-list"
>
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<li
class=
"ingredient-item"
>
<img
src=
"../imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
alt=
"
<?php
echo
$ingredient
->
name
;
?>
"
/>
<span>
<?php
echo
$ingredient
->
name
;
?>
:
<?php
echo
$ingredient
->
amount
;
?>
</span>
<img
src=
"../imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
alt=
"
<?php
echo
$ingredient
->
name
;
?>
"
/>
<span>
<?php
echo
$ingredient
->
name
;
?>
:
<?php
echo
$ingredient
->
amount
;
?>
</span>
</li>
<?php
}
?>
</ul>
<h2>
Instrucciones
</h2>
<p
class=
"instructions"
>
<?php
echo
$recipe
->
instructions
;
?>
</p>
<p
class=
"instructions"
>
<?php
echo
$recipe
->
instructions
;
?>
</p>
<?php
if
(
!
empty
(
$recipe
->
link
))
:
?>
<?php
$videoId
=
getYoutubeVideoId
(
$recipe
->
link
);
?>
<?php
if
(
$videoId
)
:
?>
<h2>
Video de la receta
</h2>
<div
class=
"video-container"
>
<iframe
width=
"560"
height=
"315"
src=
"https://www.youtube.com/embed/
<?php
echo
$videoId
;
?>
"
title=
"YouTube video player"
frameborder=
"0"
allow=
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
<iframe
width=
"560"
height=
"315"
src=
"https://www.youtube.com/embed/
<?php
echo
$videoId
;
?>
"
title=
"YouTube video player"
frameborder=
"0"
allow=
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
<?php
endif
;
?>
<?php
endif
;
?>
...
...
app/Views/templates/header.php
View file @
0a9b0608
...
...
@@ -32,7 +32,7 @@
<link
href=
"
<?=
base_url
(
"css/style.css"
)
?>
"
rel=
"stylesheet"
>
<script
src=
"https://code.jquery.com/jquery-3.6.4.min.js"
integrity=
"sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8="
crossorigin=
"anonymous"
></script>
<script
src=
"js/main.js"
></script>
</head>
...
...
@@ -55,15 +55,15 @@
<i
class=
"bi bi-list toggle-sidebar-btn"
></i>
</div>
<!-- End Logo -->
<!-- Barra de búsqueda -->
<div
class=
"search-bar"
>
<form
class=
"search-form d-flex align-items-center"
method=
"POST"
action=
"#"
>
<input
type=
"text"
id=
"search-query"
name=
"query"
placeholder=
"Buscar por receta..."
title=
"Enter search keyword"
>
title=
"Enter search keyword"
>
</form>
<div
id=
"recipe_dropdown"
class=
"recipe-dropdown"
>
<ul
id=
"recipe_list"
class=
"recipe-list list-unstyled"
></ul>
<ul
id=
"recipe_list"
class=
"ingredients-list list-unstyled"
></ul>
</div>
</div
>
<!-- Fin barra de búsqueda --
>
...
...
@@ -155,3 +155,164 @@
</nav>
<!-- End Icons Navigation -->
</header>
<!-- End Header -->
<!-- ======= Sidebar ======= -->
<aside
id=
"sidebar"
class=
"sidebar"
>
<ul
class=
"sidebar-nav"
id=
"sidebar-nav"
>
<li
class=
"nav-item"
>
<a
class=
"nav-link "
href=
"index.html"
>
<i
class=
"bi bi-grid"
></i>
<span>
Recetas
</span>
</a>
</li>
<!-- End Dashboard Nav -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro Vegano
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"vegan-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxOne"
value=
"Order one"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxOne"
>
Recetas Veganas
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav2"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro 2
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav2"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"indian-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFour"
value=
"Order four"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxFour"
>
India
</label>
</li>
</ul>
<ul
class=
"french-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFive"
value=
"Order five"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxFive"
>
Francia
</label>
</li>
</ul>
<ul
class=
"chinese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSix"
value=
"Order six"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxSix"
>
China
</label>
</li>
</ul>
<ul
class=
"mexican-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSeven"
value=
"Order seven"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxSeven"
>
México
</label>
</li>
</ul>
<ul
class=
"spanish-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEight"
value=
"Order eigth"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxEight"
>
España
</label>
</li>
</ul>
<ul
class=
"japanese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxNine"
value=
"Order nine"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxNine"
>
Japón
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav3"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Estaciones
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav3"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"winter-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTen"
value=
"Order ten"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxTen"
>
Invierno
</label>
</li>
</ul>
<ul
class=
"spring-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEleven"
value=
"Order eleven"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxEleven"
>
Primavera
</label>
</li>
</ul>
<ul
class=
"summer-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTwelve"
value=
"Order twelve"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxTwelve"
>
Verano
</label>
</li>
</ul>
<ul
class=
"autumn-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkbox13"
value=
"Order 13"
onchange=
"updateRecipeList()"
>
<label
for=
"checkbox13"
>
Otoño
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/insert_recipe"
>
<i
class=
"bi bi-file-earmark"
></i>
<span>
Subir receta
</span>
</a>
</li>
<!-- End Profile Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"https://www.instagram.com/salvaperfectti/"
>
<i
class=
"bi bi-envelope"
></i>
<span>
Contacto
</span>
</a>
</li>
<!-- End Contact Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/login"
>
<i
class=
"bi bi-box-arrow-in-right"
></i>
<span>
Registro/Login
</span>
</a>
</li>
<!-- End Login Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"http://www.homerswebpage.com/"
>
<i
class=
"bi bi-dash-circle"
></i>
<span>
Error 404
</span>
</a>
</li>
<!-- End Error 404 Page Nav -->
</ul>
</aside>
<!-- End Sidebar-->
\ No newline at end of file
public/css/style.css
View file @
0a9b0608
...
...
@@ -360,6 +360,26 @@ h6 {
.header
.search-bar
{
min-width
:
360px
;
padding
:
0
20px
;
position
:
relative
;
}
#recipe_list
{
position
:
absolute
;
top
:
100%
;
left
:
0
;
z-index
:
1
;
width
:
100%
;
max-height
:
200px
;
overflow-y
:
auto
;
background-color
:
#fff
;
border-top
:
none
;
border-radius
:
0
0
.25rem
.25rem
;
padding
:
0
;
margin
:
0
;
}
.recipe-item
{
cursor
:
pointer
;
}
@media
(
max-width
:
1199px
)
{
...
...
@@ -789,10 +809,7 @@ h6 {
}
/* Info Cards */
.dashboard
.info-card
{
padding-bottom
:
10px
;
}
s
.dashboard
.info-card
h6
{
font-size
:
28px
;
color
:
#012970
;
...
...
@@ -904,12 +921,6 @@ h6 {
padding-left
:
0
;
}
.recipe-card-link
{
display
:
block
;
text-decoration
:
none
;
color
:
inherit
;
}
.dashboard
.news
p
{
font-size
:
14px
;
color
:
#777777
;
...
...
public/imagenes/2729270.png
0 → 100644
View file @
0a9b0608
48.8 KB
public/js/insert.js
View file @
0a9b0608
...
...
@@ -25,7 +25,7 @@ recipeForm.addEventListener("submit", function (event) {
hiddenInput
.
value
=
JSON
.
stringify
(
ingredientsData
);
recipeForm
.
appendChild
(
hiddenInput
);
});
});
// Array para almacenar palabras clave seleccionadas
let
ingredients
=
[];
...
...
@@ -35,7 +35,7 @@ function searchIngredients(query) {
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
// Añadir esta línea
'X-Requested-With'
:
'XMLHttpRequest'
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
...
...
@@ -139,7 +139,7 @@ function updateSelectedIngredients() {
ingredientElement
.
appendChild
(
removeBtn
);
selectedIngredients
.
appendChild
(
ingredientElement
);
});
}
}
...
...
@@ -154,43 +154,43 @@ ingredientSearch.addEventListener('input', function (event) {
var
inputPhoto
=
document
.
getElementById
(
'photo'
);
var
imageUploadContainer
=
document
.
querySelector
(
'.image-upload-container'
);
inputPhoto
.
addEventListener
(
'change'
,
function
(
event
)
{
inputPhoto
.
addEventListener
(
'change'
,
function
(
event
)
{
displayImagePreview
(
event
.
target
.
files
[
0
]);
});
});
imageUploadContainer
.
addEventListener
(
'dragover'
,
function
(
event
)
{
imageUploadContainer
.
addEventListener
(
'dragover'
,
function
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
event
.
dataTransfer
.
dropEffect
=
'copy'
;
});
});
imageUploadContainer
.
addEventListener
(
'drop'
,
function
(
event
)
{
imageUploadContainer
.
addEventListener
(
'drop'
,
function
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
if
(
event
.
dataTransfer
.
files
.
length
>
0
)
{
displayImagePreview
(
event
.
dataTransfer
.
files
[
0
]);
inputPhoto
.
files
=
event
.
dataTransfer
.
files
;
}
});
});
function
displayImagePreview
(
file
)
{
function
displayImagePreview
(
file
)
{
var
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
}
reader
.
readAsDataURL
(
file
);
}
}
document
.
getElementById
(
'photo'
).
addEventListener
(
'change'
,
function
(
event
)
{
document
.
getElementById
(
'photo'
).
addEventListener
(
'change'
,
function
(
event
)
{
var
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
}
reader
.
readAsDataURL
(
event
.
target
.
files
[
0
]);
});
});
public/js/main.js
View file @
0a9b0608
/**
* Template Name: NiceAdmin
* Updated: Mar 09 2023 with Bootstrap v5.2.3
* Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
*/
(
function
()
{
(
function
()
{
const
recipesSearch
=
document
.
querySelector
(
'#search-query'
);
function
search_recipe
(
query
)
{
fetch
(
'/search_recipe'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
searchResults
)
=>
{
// Limpiar la lista de recetas coincidentes anterior
const
recipeList
=
document
.
querySelector
(
'#recipe_list'
);
recipeList
.
innerHTML
=
''
;
// Agregar recetas coincidentes a la lista desplegable
searchResults
.
forEach
((
recipe
)
=>
{
const
listItem
=
document
.
createElement
(
'li'
);
listItem
.
classList
.
add
(
'recipe-item'
,
'd-flex'
,
'align-items-center'
,
'p-2'
,
'mb-1'
,
'bg-light'
,
'rounded'
);
const
nameElement
=
document
.
createElement
(
'span'
);
nameElement
.
textContent
=
recipe
.
name
;
nameElement
.
classList
.
add
(
'recipe-name'
,
'flex-grow-1'
);
listItem
.
appendChild
(
nameElement
);
listItem
.
setAttribute
(
'data-id'
,
recipe
.
id
);
listItem
.
setAttribute
(
'title'
,
'Haz clic para seleccionar '
+
recipe
.
name
);
listItem
.
setAttribute
(
'href'
,
'/recipe/'
+
recipe
.
id
);
listItem
.
addEventListener
(
'click'
,
function
()
{
window
.
location
.
href
=
this
.
getAttribute
(
'href'
);
});
recipeList
.
appendChild
(
listItem
);
});
});
}
// Agregar evento para ir a una receta cuando se seleccione
recipesSearch
.
addEventListener
(
'input'
,
function
(
event
)
{
// Llamar a la función search_recipe para buscar y mostrar recetas coincidentes
search_recipe
(
event
.
target
.
value
);
});
"use strict"
;
/**
...
...
@@ -42,7 +88,7 @@
* Sidebar toggle
*/
if
(
select
(
'.toggle-sidebar-btn'
))
{
on
(
'click'
,
'.toggle-sidebar-btn'
,
function
(
e
)
{
on
(
'click'
,
'.toggle-sidebar-btn'
,
function
(
e
)
{
select
(
'body'
).
classList
.
toggle
(
'toggle-sidebar'
)
})
}
...
...
@@ -51,7 +97,7 @@
* Search bar toggle
*/
if
(
select
(
'.search-bar-toggle'
))
{
on
(
'click'
,
'.search-bar-toggle'
,
function
(
e
)
{
on
(
'click'
,
'.search-bar-toggle'
,
function
(
e
)
{
select
(
'.search-bar'
).
classList
.
toggle
(
'search-bar-show'
)
})
}
...
...
@@ -115,7 +161,7 @@
* Initiate tooltips
*/
var
tooltipTriggerList
=
[].
slice
.
call
(
document
.
querySelectorAll
(
'[data-bs-toggle="tooltip"]'
))
var
tooltipList
=
tooltipTriggerList
.
map
(
function
(
tooltipTriggerEl
)
{
var
tooltipList
=
tooltipTriggerList
.
map
(
function
(
tooltipTriggerEl
)
{
return
new
bootstrap
.
Tooltip
(
tooltipTriggerEl
)
})
...
...
@@ -288,8 +334,8 @@
var
needsValidation
=
document
.
querySelectorAll
(
'.needs-validation'
)
Array
.
prototype
.
slice
.
call
(
needsValidation
)
.
forEach
(
function
(
form
)
{
form
.
addEventListener
(
'submit'
,
function
(
event
)
{
.
forEach
(
function
(
form
)
{
form
.
addEventListener
(
'submit'
,
function
(
event
)
{
if
(
!
form
.
checkValidity
())
{
event
.
preventDefault
()
event
.
stopPropagation
()
...
...
@@ -313,7 +359,7 @@
const
mainContainer
=
select
(
'#main'
);
if
(
mainContainer
)
{
setTimeout
(()
=>
{
new
ResizeObserver
(
function
()
{
new
ResizeObserver
(
function
()
{
select
(
'.echart'
,
true
).
forEach
(
getEchart
=>
{
echarts
.
getInstanceByDom
(
getEchart
).
resize
();
})
...
...
@@ -321,103 +367,90 @@
},
200
);
}
/*
function search_recipe(query) {
if (query.trim() === '') {
document.querySelector('#recipe_dropdown').style.display = 'none';
return;
/* function updateRecipeList() {
// Obtén el estado de los checkboxes
var vegan = document.getElementById("checkboxOne").checked;
var countries = ['India', 'Francia', 'China', 'México', 'España', 'Japón'];
var country = '';
for (var i = 0; i < countries.length; i++) {
if (document.getElementById("checkbox" + (i + 4)).checked) {
country = countries[i];
break;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/search_recipe', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
var searchResults = JSON.parse(xhr.responseText);
const recipeList = document.querySelector('#recipe_list');
recipeList.innerHTML = '';
if (searchResults.length > 0) {
document.querySelector('#recipe_dropdown').style.display = 'block';
} else {
document.querySelector('#recipe_dropdown').style.display = 'none';
}
searchResults.forEach((recipe) => {
const listItem = document.createElement('li');
listItem.classList.add('recipe-item');
const nameElement = document.createElement('span');
nameElement.textContent = recipe.name;
listItem.appendChild(nameElement);
recipeList.appendChild(listItem);
});
} catch (error) {
console.error('Error parsing JSON response:', error);
var seasons = ['Invierno', 'Primavera', 'Verano', 'Otoño'];
var season = '';
for (var i = 0; i < seasons.length; i++) {
if (document.getElementById("checkbox" + (i + 10)).checked) {
season = seasons[i];
break;
}
} else if (xhr.readyState === 4) {
console.error('Error in request:', xhr.status, xhr.statusText);
}
};
xhr.send('query=' + encodeURIComponent(query));
}
// Enviar una solicitud AJAX a tu controlador de recetas
var xhr = new XMLHttpRequest();
xhr.open("POST", "/recipes/get_filtered_recipes", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
// Actualizar el contenido de la página con las recetas filtradas
var recipes = JSON.parse(this.responseText);
var recipeList = document.getElementById("recipe-list");
recipeList.innerHTML = ''; // Limpiar la lista de recetas
document.addEventListener('click', function (event
) {
if (!event.target.closest('.search-bar')) {
document.querySelector('#recipe_dropdown').style.display = 'none'
;
for (var i = 0; i < recipes.length; i++
) {
var recipeHTML = generateRecipeHTML(recipes[i]);
recipeList.innerHTML += recipeHTML
;
}
});
*/
function
search_recipe
(
query
)
{
fetch
(
'/search_recipe'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
// Añadir esta línea
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
searchResults
)
=>
{
// Limpiar la lista de ingredientes coincidentes anterior
const
recipeList
=
document
.
querySelector
(
'#recipe_dropdown'
);
recipeList
.
innerHTML
=
''
;
// Agregar ingredientes coincidentes a la lista desplegable
searchResults
.
forEach
((
ingredient
)
=>
{
const
listItem
=
document
.
createElement
(
'li'
);
listItem
.
classList
.
add
(
'recipe-item'
,
'd-flex'
,
'align-items-center'
,
'p-2'
,
'mb-1'
,
'bg-light'
,
'rounded'
);
const
nameElement
=
document
.
createElement
(
'span'
);
nameElement
.
textContent
=
ingredient
.
name
;
nameElement
.
classList
.
add
(
'recipe-name'
,
'flex-grow-1'
);
listItem
.
appendChild
(
nameElement
);
listItem
.
setAttribute
(
'data-id'
,
recipes
.
id
);
listItem
.
setAttribute
(
'title'
,
'Haz clic para seleccionar '
+
recipes
.
name
);
// Añade información adicional al ingrediente
recipeList
.
appendChild
(
listItem
);
});
});
}
};
xhr.send("vegan=" + vegan + "&country=" + country + "&season=" + season);
}
// Agregar evento para agregar ingredientes cuando se presiona Enter en el campo de búsqueda
ingredientSearch
.
addEventListener
(
'search'
,
function
(
event
)
{
// Llamar a la función searchIngredients para buscar y mostrar ingredientes coincidentes
search_recipe
(
event
.
target
.
value
);
});
})();
\ No newline at end of file
function generateRecipeHTML(recipe) {
var recipeHTML = `
<div class="card info-card sales-card"
onclick="window.location.href='<?php echo base_url('recipe/' . $row->id); ?>'">
<a href="<?php echo base_url('recipe/' . $row->id); ?>">
</a>
<div class="row flex-nowrap">
<div class="col-lg-3 col-md-4 col-sm-12 imagen-container">
<img src="<?php echo base_url('recipe/image/' . $row->id); ?>" alt=""
class="img-fluid rounded-start">
</div>
<div class="col-lg-9 col-md-8 col-sm-12">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Opciones</h6>
</li>
<li><a class="dropdown-item" href="#">Guardar</a></li>
<li><a class="dropdown-item" href="#">Compartir</a></li>
</ul>
</div>
<div class="card-body">
<h5 class="card-title">
<?php echo $row->name; ?> <span>|
<?php echo $row->origin; ?>
</span>
</h5>
<!--ingredientes-->
<?php foreach ($ingredients as $ingredient) { ?>
<div class="chip" title="Cantidad: <?php echo $ingredient->amount; ?>">
<img src="imagenes/ingredientes/<?php echo $ingredient->icon; ?>">
<b style="font-size: 14px">
<?php echo $ingredient->name; ?>
</b>
</div>
<?php } ?>
<!--fin ingredientes-->
</div>
</div>
</div>
</div>`;
return recipeHTML;
} */
})();
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment