I'm working with nuxt-dropzone https://www.npmjs.com/package/nuxt-dropzone to upload images. I would also like to use it as an image library, so users can view their images in the same way they uploaded them. I'm not finding a lot of documentation on nuxt-dropzone, so I'm wondering how to pre-load the images into the dropzone.
Here's my code:
<template>
<v-card style="border-radius: 0; box-shadow: none" class="px-10">
<v-row justify="center">
<div class="pt-8" style="width: 1050px">
<v-tabs
:centered="false"
:hide-slider="true"
:fixed-tabs="false"
class="hls-tabs py-1"
height="100%"
>
<v-tab
:ripple="false"
class="hls-tab background py-3 tabs-0"
active-class="primary tab-active"
>
<div class="background px-1 tab-container">
<p class="tab-content py-4 subheading">Upload Image</p>
</div>
</v-tab>
<v-tab
:ripple="false"
class="hls-tab background py-3 tabs-1"
active-class="primary tab-active"
>
<div class="background px-1 tab-container">
<p class="tab-content py-4 subheading">Image Library</p>
</div>
</v-tab>
<v-tab-item class="tab-item tab-item-0">
<div class="tab-item-content px-15 py-15" style="min-height: 400px">
<dropzone
id="imageUpload"
ref="imageUpload"
v-model="testImages"
:options="options"
:destroy-dropzone="true"
:style="
isUploaded
? 'border: 0; border-radius: 25px'
: 'border: 4px dashed rgb(111, 118, 167); border-radius: 25px'
"
#vdropzone-file-added="onFileAdded"
#vdropzone-removed-file="onFileRemove"
>
<v-icon size="60" color="rgb(176, 173, 173)" class="pb-5"
>mdi-file-upload-outline</v-icon
>
<h3 style="color: rgb(111, 118, 167)" class="pb-5">
To Upload Media, drag files here
</h3>
<h3 style="color: rgb(111, 118, 167)" class="pb-5">OR</h3>
<h3 style="color: rgb(111, 118, 167)">click to select file</h3>
</dropzone>
</div>
</v-tab-item>
<v-tab-item class="tab-item tab-item-0">
<div class="tab-item-content" style="min-height: 400px">
<dropzone
id="imageLibrary"
ref="imageLibrary"
:destroy-dropzone="true"
:options="libraryOptions"
>
<div
v-for="image in testImages"
:key="image.dataURL"
class="dropzone-previews dropzone"
>
<img :src="image.dataUrl" :height="200" :width="200" />
</div>
</dropzone>
</v-tabs>
</div>
</v-row>
</v-card>
</template>
<script>
import dropzone from 'nuxt-dropzone';
import 'nuxt-dropzone/dropzone.css';
import defaultImage from '~/assets/empty_photo.png';
import second from '~/assets/google_mic.png';
export default {
name: 'ImageUploadDialog',
components: { dropzone },
data() {
return {
images: [],
youtubeUrl: '',
isUploaded: false,
testImages: [defaultImage, second],
options: {
url: 'https://httpbin.org/post',
addRemoveLinks: true
},
libraryOptions: {
url: 'https://httpbin.org/post'
}
};
},
methods: {
handleClose() {
this.$nuxt.$emit('close-image-upload');
},
handleSave() {
for (const file of this.$refs.imageUpload.dropzone.files) {
this.images.push(file);
}
const lastIndex = this.youtubeUrl.lastIndexOf('/');
const youtubeIdentifier = this.youtubeUrl.slice(lastIndex + 1);
},
onFileAdded() {
this.isUploaded = true;
},
onFileRemove() {
if (this.$refs.imageUpload.dropzone.files.length === 0) {
this.isUploaded = false;
}
}
}
};
</script>
I've tried to use the "instance" to emit on load, but I keep getting an error that it cannot read the property of dropzone.
mounted() {
const instance = this.$refs.imageLibrary.dropzone;
for (const image of this.testImages) {
const mockFile = { name: image, size: 12345 };
instance.emit('addedFile', mockFile);
}
},
Use dropzone.js manuallyAddFile() function, with nextTick to render uploaded pictures correctly
mounted(){
this.$nextTick(() => {
for(const image of this.testImages){
let url = `${imageLink}`;
let file = { size: 123, name: image, type: "image/png" };
this.$refs.myVueDropzone1.manuallyAddFile(file, url);
}
});
}
Okay so what was happening was because the dropzones are in a drawer, they were being loaded as soon as the page loads. The refs were only being recognized when the dropzone was actually displayed on the screen. When I did a 'window.setTimeout', the refs worked. So the way I solved it was to put the second dropzone in its own component.
The second component then looked like this:
<template>
<div class="tab-item-content" style="min-height: 400px">
<dropzone
id="imageLibrary"
ref="imageLibrary"
:destroy-dropzone="true"
:options="libraryOptions"
>
</dropzone>
</div>
</template>
<script>
import dropzone from 'nuxt-dropzone';
import 'nuxt-dropzone/dropzone.css';
import defaultImage from '~/assets/empty_photo.png';
import second from '~/assets/google_mic.png';
export default {
name: 'ImageLibrary',
components: { dropzone },
data() {
return {
testImages: [defaultImage, second],
libraryOptions: {
url: 'https://httpbin.org/post'
}
};
},
mounted() {
for (const image of this.testImages) {
console.log('image', image);
const url = `${image}`;
const file = { size: 123, name: `${image}`, type: 'image/png' };
this.$refs.imageLibrary.manuallyAddFile(file, url);
}
}
};
</script>
Related
I have four pictures, when I hover the mouse over them, a certain component is displayed from below, but I still need to bind the click event, that is, when I click on the picture, the component should be displayed; when the component is clicked again, the problem is that I cannot bind two events at once at the same time
I understand that when the user hovers over the component, it will be immediately displayed and the click event will be useless, but I will need it in the mobile version
You can also look at my code in codesandbox
<template>
<div>
<div class="enjoy_headline_container">
<div class="EnjoyGirlsContainer">
<div>
<h3 style="margin: 0"></h3>
</div>
<div class="EnjoyGirlsList">
<div
v-for="(chunk, index) in Math.ceil(EnjoyGirlsList.length / 2)"
:key="'chunk-' + index"
:class="'wrap-' + index"
>
<div
v-for="(item, index) in EnjoyGirlsList.slice(
(chunk - 1) * 2,
chunk * 2
)"
:key="'img-' + index"
class="EnjoyCard"
:class="'EnjoyCard-' + index"
>
<div v-on:click="isHidden = !isHidden">
<img
#mouseover="mouseOver(item, (hover = true))"
:src="item.imagePath"
alt="Snow"
/>
</div>
<div class="EnjoyCardContainer">
<div
:style="{ background: item.textColor }"
class="EnjoyCardChildContainer"
>
<h3 class="EnjoyCardChildContainerTitleName">
{{ item.titleName }}
</h3>
</div>
</div>
<div
v-if="selected === item && !isHidden"
class="below-all-description EnjoyGirlsHoverEffect"
>
<div class="next-to-description EnjoyGirlsHoverEffect">
<div
style="width: 100%; display: flex; justify-content: center"
v-for="(enjoy, index) in EnjoyGirlsList"
:key="index"
>
<div
#mouseleave="mouseout(enjoy, (hover = false))"
class="EnjoyGirlsChildHoverEffect"
>
<component
v-show="enjoy.hovered"
v-bind:is="enjoy.componentName"
></component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="!isHidden" class="below-all-description">
<template v-if="selected === null"></template>
<template v-else>
<div
style="width: 100%; display: flex; justify-content: center"
v-for="(enjoy, index) in EnjoyGirlsList"
:key="index"
>
<div
#mouseleave="mouseout(enjoy, (hover = false))"
class="EnjoyGirlsChildHoverEffect"
>
<component
v-show="enjoy.hovered"
v-bind:is="enjoy.componentName"
></component>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
import EnjoyBlue from "./components/EnjoyBlue";
import EnjoyGreen from "./components/EnjoyGreen";
import EnjoyYellow from "./components/EnjoyYellow";
import EnjoyRed from "./components/EnjoyRed";
export default {
name: "HomePage",
components: {
EnjoyRed,
EnjoyYellow,
EnjoyGreen,
EnjoyBlue,
},
data() {
return {
isHidden: false,
selected: null,
hover: false,
sectionGirlsListComponentsNames: [
"EnjoyRed",
"EnjoyYellow",
"EnjoyGreen",
"EnjoyBlue",
],
EnjoyGirlsList: [
{
imagePath: "https://i.ibb.co/mCpNXhG/IMG-6061-min.png",
titleName: "TEENS",
textColor: "#74C8C5",
hovered: false,
componentName: "EnjoyBlue",
},
{
imagePath: "https://i.ibb.co/WvJjwsN/Rectangle-2.png",
titleName: "MINXES",
textColor: "#76ED00",
hovered: false,
componentName: "EnjoyGreen",
},
{
imagePath: "https://i.ibb.co/7khc5f0/Rectangle-3.png",
titleName: "MILFS",
textColor: "#FFE600",
hovered: false,
componentName: "EnjoyYellow",
},
{
imagePath: "https://i.ibb.co/6nz97Bw/Rectangle-4.png",
titleName: "COURGARS",
textColor: "#CC003D",
hovered: false,
componentName: "EnjoyRed",
},
],
};
},
methods: {
mouseOver: function (enjoy) {
this.EnjoyGirlsList.forEach((enjoy) => (enjoy.hovered = false));
this.selected = enjoy;
enjoy.hovered = true;
if (this.hover) {
console.log("4949494");
}
},
mouseout: function (enjoy) {
this.selected = null;
enjoy.hovered = false;
},
mouseEnter: function () {},
Prev() {
this.$refs.carousel.prev();
},
showNext() {
this.$refs.carousel.next();
},
},
};
</script>
And so if you looked at this code in codesandbox (I left the link at the top), then you might have noticed that hover only works the first time after that it does not work, only the click event works
Your click event toggles isHidden. When you click on it you set isHidden to true. After that it won't show, if you hover over it since you are hiding it with v-if:
<div v-if="!isHidden" class="below-all-description">
...
</div>
Solution:
In your mouseOver function you explicitly have to set isHidden to false.
methods: {
mouseOver: function (enjoy) {
this.isHidden = false;
this.EnjoyGirlsList.forEach((enjoy) => (enjoy.hovered = false));
...
}
...
}
I have two pictures, when hovering over the first picture, a certain component is displayed and the second picture works in a similar way, which displays another component, my problems began when I decided to apply animation when hovering over the picture, that is, I wanted to make it appear a certain component with animation, but the problem is that the animation works only for the first component, and for the second component, not only the animation does not work, it is also not displayed, you can see my code in the sandbox
If you looked at my code, you might have noticed that I display components using v-for, but when I tried to display components manually (that is, without a loop), everything worked fine for me, that is, like this
<div style="margin-top: 200px;">
<slide-y-up-transition>
<RedExperience v-show="img1" key="img1"/>
</slide-y-up-transition>
<slide-y-up-transition>
<OrangeExperience v-show="img2" key="img2"/>
</slide-y-up-transition>
<slide-y-up-transition>
<GreenExperience v-show="img4" key="img4"/>
</slide-y-up-transition>
</div>
Here is my code from sandbox
<template>
<div>
<div style="display: flex; justify-content: center">
<div v-bind:key="index" v-for="(girl, index) in girls">
<img
style="width: 200px; height: 200px; margin: 5px"
#mouseover="mouseOver(girl)"
#mouseout="mouseout(girl)"
v-bind:src="girl.imgSrc"
alt="Snow"
/>
</div>
</div>
<slide-y-up-transition>
<component
v-for="(girl, index) in girls"
v-show="girl.hovered"
v-bind:key="index"
v-bind:is="girl.componentName"
></component>
</slide-y-up-transition>
</div>
</template>
<script>
import { SlideYUpTransition } from "vue2-transitions";
import MyFirstComponent from "./colors/myycomponent";
import myOtherComponent from "./colors/myothercomponent";
export default {
name: "HelloWorld",
components: {
MyFirstComponent,
myOtherComponent,
SlideYUpTransition,
},
data() {
return {
componentNames: ["MyFirstComponent", "myOtherComponent"],
girls: [
{
imgSrc:
"https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg",
hovered: false,
hoverColor: "#337700",
componentName: "MyFirstComponent",
},
{
imgSrc:
"https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg",
hovered: false,
hoverColor: "#123456",
componentName: "myOtherComponent",
},
],
};
},
methods: {
mouseOver: function (girl) {
girl.hovered = true;
},
mouseout: function (girl) {
girl.hovered = false;
},
},
};
</script>
the problem is in your loop, transitions can only be used on a single element.
So do your loop this way to solve it.
<div v-for="(girl, index) in girls" v-bind:key="index">
<slide-y-up-transition>
<component
v-show="girl.hovered"
v-bind:is="girl.componentName"
></component>
</slide-y-up-transition>
</div>
your full code has to be like this.
<template>
<div>
<div style="display: flex; justify-content: center">
<div v-bind:key="index" v-for="(girl, index) in girls">
<img
style="width: 200px; height: 200px; margin: 5px"
#mouseover="mouseOver(girl, index)"
#mouseout="mouseout(girl, index)"
v-bind:src="girl.imgSrc"
alt="Snow"
/>
</div>
</div>
<div v-for="(girl, index) in girls" v-bind:key="index">
<slide-y-up-transition >
<component
v-show="girl.hovered"
v-bind:is="girl.componentName"
></component>
</slide-y-up-transition>
</div>
</div>
</template>
<script>
import { SlideYUpTransition } from "vue2-transitions";
import MyFirstComponent from "./colors/myycomponent";
import myOtherComponent from "./colors/myothercomponent";
export default {
name: "HelloWorld",
components: {
MyFirstComponent,
myOtherComponent,
SlideYUpTransition,
},
data() {
return {
componentNames: ["MyFirstComponent", "myOtherComponent"],
girls: [
{
imgSrc:
"https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg",
hovered: false,
hoverColor: "#337700",
componentName: "MyFirstComponent",
},
{
imgSrc:
"https://i.pinimg.com/originals/a9/76/af/a976af5c7bf3cc5b05a1b301334e0f68.jpg",
hovered: false,
hoverColor: "#123456",
componentName: "myOtherComponent",
},
],
};
},
methods: {
mouseOver: function (girl, index) {
this.girls[index].hovered = true;
},
mouseout: function (girl, index) {
this.girls[index].hovered = false;
},
},
};
</script>
i have a costume made Tabs and Tab from Laracasts Tabs Tutorial , and it work fine, but i need to load data when the tab is changed and i did that but when the data is loaded,
i need to render another component which have accordion and inside each accordion tab their some charts components need to be render also
so how can i render the accordion with the charts components when the Tabs tab is changed
Tabs Component:
<template>
<div class="tab-container -mt-px w-full">
<div class="tabs">
<ul class="list-reset flex border-b">
<li class="" v-for="(tab, index) in tabs" role="tab">
<a class="bg-white inline-block font-semibold hover:no-underline"
:class="[
{
'active-tab-link text-blue-dark border-l border-r active-tab-link-p': tab.isActive,
'text-blue hover:text-blue-darker non-active-tab-link-p': !tab.isActive
},
]"
:href="tab.href" #click="selectedTab(tab)">
{{tab.name}}
</a>
</li>
</ul>
</div>
<div class="tabs-details px-4 w-full">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "Tabs",
data() {
return {
tabs: []
};
},
created() {
this.tabs = this.$children;
// this.selectFirstTab();
},
methods: {
selectedTab(selectedTab) {
this.$emit('onTabChange', selectedTab);
this.tabs.map((tab, index) => {
tab.isActive = (tab.name === selectedTab.name)
});
},
}
}
</script>
Tab Component:
<template>
<div class="w-full" role="tabpanel" v-show="isActive">
<slot></slot>
</div>
</template>
<script>
import {isEmpty} from "../helpers/Helper";
export default {
name: "Tab",
props: {
name: {
type: String,
required: true
},
selected: {
type: Boolean,
default: false,
},
isFirst: {
type: Boolean,
default: false,
},
},
data() {
return {
// isActive: false,
isActive: true,
// isFirst: this.isFirst
};
},
computed: {
href() {
return this.formatHref(this.name);
},
},
mounted() {
this.selectTabFromURL();
},
methods: {
selectTabFromURL() {
let hash = this.$route.hash;
if (this.selected) {
this.isActive = this.selected;
} else if (!isEmpty(hash)) {
this.isActive = (this.formatHref(this.name) === hash);
} else if (this.isFirst) {
this.isActive = this.isFirst;
} else if (!this.isFirst && this.isActive) {
this.isActive = !this.isActive;
}
},
formatHref(id) {
return `#${id.toLowerCase().replace(/ /g, '-')}`;
}
}
}
</script>
the main component:
<template>
<!--components tabs start-->
<div class="flex flex-col">
<div class="mt-3 border-t-4 border-primary-color border-6 bg-white">
<div class=" border border-gray-400 lg:border-l-0 lg:border-t lg:border-gray-400 rounded-b lg:rounded-b-none lg:rounded-r leading-normal">
<Tabs #onTabChange="handleTabChange">
<!--:name="`${tab.name} - ${tab.component.type}`"-->
<Tab v-for="(tab, index) in page.tabs"
:key="tab.id"
:id="tab.slug"
:name="tab.name"
:slug="tab.slug"
:isFirst="index === 0"
>
<div>
How to render the dynamic accordion with the charts one time only no need to re-render
</div>
</Tab>
</Tabs>
</div>
</div>
</div>
<!--components tabs end-->
</template>
in normal HTML and JQuery, i can load the data and the render the result and append it to the wanted tab how can we do this with vue, dose the dynamic component help in this case ?
I searched for a solution and found and implement the "Creating Vue.js Component Instances Programmatically"
This is in relation to implementing drag and drop using vue. I have a draggable div container.
// BoardColumn Component Parent Container
<template>
<div
draggable
#dragover.prevent
#dragenter.prevent
#drop="dropColumn($event, columnIndex)"
#dragstart="setPickColumnInfo($event, columnIndex)"
>
<div class="column bg-grey-light m-4">
<div class="flex items-center mb-2 font-bold">
{{ getColumnName() }}
</div>
<div class="list-reset">
<TaskCard
class="task"
v-for="(task, $taskIndex) of columnData.tasks"
:key="$taskIndex"
v-bind:task="task"
v-bind:taskIndex="$taskIndex"
v-bind:columnIndex="columnIndex"
/>
</div>
<input
type="text"
class="block p-2 w-full bg-transparent"
placeholder="+Enter a new task"
#keyup.enter="createTask($event, columnData.tasks)"
/>
</div>
</div>
</template>
Inside this container is another draggable container TaskCard. i'm able to drag the parent container and the child container without any issues. However, the callback functions related to only parent container BoardColumn gets fired regardless of which container is being dragged.
The function definitions are below. Any help would be greatly appreciated.
// TaskCard.vue Child container
<template>
<div
draggable
#dragover.prevent
#dragenter.prevent
#dragstart="setPickupTaskInfo($event, taskIndex, columnIndex)"
#dragend="dropTask($event, taskIndex, columnIndex)"
#click="goToTask(task)"
v-if="isTaskOpen === false"
>
<span class="w-full flex-no-shrink font-bold">
{{ task.name }}
</span>
<p v-if="task.description" class="w-full flex-no-shrink mt-1 text-sm">
{{ task.description }}
</p>
</div>
<div class="task-bg" #click.self="close" v-else>
<router-view />
</div>
</template>
// BoardColumn JS
import TaskCard from "#/components/TaskCard/TaskCard.vue";
export default {
components: {
TaskCard
},
props: ["columnData", "columnIndex"],
methods: {
getColumnName() {
return this.columnData.name;
},
createTask(e, tasks) {
this.$store.commit("CREATE_TASK", {
tasks,
name: e.target.value
});
e.target.value = "";
},
setPickColumnInfo(e, fromColumnIndex) {
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.dropEffect = "move";
e.dataTransfer.setData("from-column-index", fromColumnIndex);
e.dataTransfer.setData("type", "column");
},
moveColumn(fromColumnIndex, toColumnIndex) {
this.$store.commit("MOVE_COLUMN", {
fromColumnIndex,
toColumnIndex
});
},
dropColumn(e, toColumnIndex) {
if (e.dataTransfer.getData("type") === "column") {
this.moveColumn(
e.dataTransfer.getData("from-column-index"),
toColumnIndex
);
console.log(e.dataTransfer.getData("type"));
}
}
}
};
// TaskCard JS
export default {
props: ["task", "taskIndex", "columnIndex"],
data() {
return {
isTaskOpen: false
};
},
methods: {
goToTask(task) {
this.$router.push({ name: "task", params: { id: task.id } });
this.isTaskOpen = true;
},
close() {
this.$router.push({ name: "board" });
this.isTaskOpen = false;
},
setPickupTaskInfo(e, fromTaskIndex, fromColumnIndex) {
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.dropEffect = "move";
e.dataTransfer.setData("from-task-index", fromTaskIndex);
e.dataTransfer.setData("from-column-index", fromColumnIndex);
e.dataTransfer.setData("type", "task");
console.log(e);
},
moveTask(e, toTaskIndex, toColumnIndex) {
const fromColumnIndex = e.dataTransfer.getData("from-column-index");
const fromTaskIndex = e.dataTransfer.getData("from-task-index");
this.$store.commit("MOVE_TASK", {
fromTaskIndex,
fromColumnIndex,
toTaskIndex,
toColumnIndex
});
},
dropTask(e, toTaskIndex, toColumnIndex) {
if (e.dataTransfer.getData("type") === "task") {
console.log(e.dataTransfer.getData("type"));
this.moveTask(e, toTaskIndex, toColumnIndex);
}
}
}
};
I want to create simple image gallery with lightbox modals. I found this library and copied example source, but it doesn't work. <Gallery images={IMAGES}/> gives nothing, iterraly nothing is displayed in browser.
Its my code:
import React, {Component} from 'react';
import './placeDetails.css'
/* Importing axois */
import axios from 'axios';
/* Importing animations */
import Fade from 'react-reveal/Fade';
/* Importing gallery library */
import Gallery from 'react-grid-gallery';
export default class placeDetails extends Component {
getInitialState(){
/* Getting data from api */
this.GetDetailsFromApi();
}
constructor(props) {
super(props);
this.state ={
data: "initial_value",
ReviewsVisible: false,
GalleryShown: false,
}
}
/* This function handles clicks of reviews header */
ReviewsHeaderClick() {
let value = this.state.ReviewsVisible;
this.setState({
ReviewsVisible: !value
})
}
GalleryHeaderClick(){
let value = this.state.GalleryShown;
this.setState({
GalleryShown: !value
})
this.GetGalleryLinks();
}
GetGalleryLinks(){
/* Getting ID of requested place */
let place_id = localStorage.getItem('SelectedPlaceID');
/* Setting up URL */
let url = "http://localhost:8000/api/image_gallery/"+place_id;
/* Requesting my backend to get images links list */
/* Requesting my backend */
axios({
method: 'get',
url: url,
headers: {
"content-type": "application/json"
}
}).then((response) => {
/* Getting data */
let data = response.data[0].json_data;
let final_data = [];
for (var i = 0; i < data.length; i++) {
//console.log(data[i]);
/* Every photo will be represented by one object with various propeties */
let object = new Object();
/* Setting propeties under names that are compatible with "react-grid-gallery" library */
object.src = data[i].img_url;
object.thumbnailWidth = data[i].width;
object.thumbnailHeight = data[i].height;
object.thumbnail = data[i].img_url;
final_data.push(object);
}
console.log(final_data)
/* Sending got data to sessionStorage as JSON string, and setting details to correct one */
localStorage.setItem("place_gallery_data", JSON.stringify(final_data));
}).catch(function (error) {
console.log(error)
});
this.forceUpdate()
}
render() {
/* Setting data */
let data = JSON.parse(localStorage.getItem("place_details_data"));
let images = JSON.parse(localStorage.getItem("place_gallery_data"));
console.log(images);
const IMAGES =
[{
src: "https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg",
thumbnail: "https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 174,
isSelected: true,
caption: "After Rain (Jeshu John - designerspics.com)"
},
{
src: "https://c2.staticflickr.com/9/8356/28897120681_3b2c0f43e0_b.jpg",
thumbnail: "https://c2.staticflickr.com/9/8356/28897120681_3b2c0f43e0_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 212,
tags: [{value: "Ocean", title: "Ocean"}, {value: "People", title: "People"}],
caption: "Boats (Jeshu John - designerspics.com)"
},
{
src: "https://c4.staticflickr.com/9/8887/28897124891_98c4fdd82b_b.jpg",
thumbnail: "https://c4.staticflickr.com/9/8887/28897124891_98c4fdd82b_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 212
}]
/* This function returns html with reviews */
function Reviews(props) {
const content = props.reviews.map((review) =>
<div key={review.id} className="mt-5">
<header>
<h4 id={review.place_id} onClick={review.getComponent}> {review.name} </h4>
</header>
<div className="info mt-3 px-4">
{review.author_name} <br/>
<div className="mt-2"> {review.text} </div> <br/>
<div> <b>Rating:</b> {review.rating} </div> <br/>
</div>
</div>
);
return (
<div>
{content}
</div>
);
}
return (
<div className="place_details_component">
<div className="containter">
<div className="row">
<div className="spacer col-1"></div>
<header className="col-10 p-3 py-5">
<h2> Details of
<div className="place_name"> {data.name}!</div>
</h2>
</header>
<div className="spacer col-1"></div>
Back to places list!
Back to home!
<div className="col-12"> <b>Address:</b> {data.vicinity} </div>
<div className="col-12"> <b>Website:</b> {data.website} </div>
<div className="col-12"> <b>Phone:</b> {data.formatted_phone_number} </div>
<div className="col-12 mb-5"> <b>Excat address:</b> {data.formatted_address} </div>
<div className="col-12"> <b>Rating:</b> {data.rating} </div>
<div className="col-12"> <b>Number of ratings:</b> {data.user_ratings_total} </div>
<div className="col-12" onClick={this.ReviewsHeaderClick.bind(this)}>
<b>Reviews:</b>
{ this.state.ReviewsVisible && <span className="up_arrow"> ▲ </span> }
{ !this.state.ReviewsVisible && <span className="dropdown_arrow"> ▼ </span> }
</div>
<Fade when={this.state.ReviewsVisible}>
{ this.state.ReviewsVisible &&
<Reviews reviews={data.reviews} className="" getComponent={this.getComponent}/>
}
</Fade>
<header className="col-12 mt-5 px-5" onClick={this.GalleryHeaderClick.bind(this)}>
<span className="gallery_header"> Photos linked with this place: </span>
{ this.state.GalleryShown && <span className="up_arrow"> ▲ </span> }
{ !this.state.GalleryShown && <span className="dropdown_arrow"> ▼ </span> }
</header>
<Fade when={this.state.GalleryShown}>
</Fade>
<Gallery images={IMAGES}/>
</div>
</div>
</div>
);
}
}
I am sure I am missing something obvious but I can't find it myself.