diff --git a/cypress/integration/list_zap_all_spec.js b/cypress/integration/list_zap_all_spec.js index 4a50552..243ff45 100644 --- a/cypress/integration/list_zap_all_spec.js +++ b/cypress/integration/list_zap_all_spec.js @@ -15,21 +15,21 @@ describe("test list all products", function() { it("contains list first page", function() { cy.wait(1000); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); cy.get("[data-cy=7baf2775d4a2]").should("not.be.visible"); cy.get("[data-cy=a0f9d9647551]").should("not.be.visible"); - cy.contains("fed26dbe5881"); - cy.contains("3e1b5315da17"); + cy.contains("Apartamento para Locação, 77m²"); + cy.contains("Apartamento para Locação, 656m²"); }); it("click next page", function() { cy.get("[data-cy=next]").click(); }); it("contains page 2", function() { cy.get("[data-cy=b154e19dcf71]").should("not.be.visible"); - cy.contains("45e188400618"); + cy.contains("Apartamento à Venda, 150m²"); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); }); it("click last page", function() { @@ -37,9 +37,9 @@ describe("test list all products", function() { }); it("contains last page", function() { cy.get("[data-cy=c8bcd9880342]").should("be.visible"); - cy.contains("3a1de7365c7b"); + cy.contains("Apartamento à Venda, 360m²"); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); }); it("click previous page", function() { @@ -47,9 +47,9 @@ describe("test list all products", function() { }); it("contains page 19", function() { cy.get("[data-cy=5d63d877585f]").should("be.visible"); - cy.contains("ff064a715bad"); + cy.contains("Apartamento para Locação, 140m²"); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); }); it("click first page", function() { @@ -57,9 +57,9 @@ describe("test list all products", function() { }); it("contains first page", function() { cy.get("[data-cy=7baf2775d4a2]").should("not.be.visible"); - cy.contains("3e1b5315da17"); + cy.contains("Apartamento para Locação, 656m²"); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); }); it("click next page", function() { @@ -67,13 +67,15 @@ describe("test list all products", function() { }); it("contains page 2", function() { cy.get("[data-cy=b154e19dcf71]").should("not.be.visible"); - cy.contains("45e188400618"); + cy.contains("Apartamento à Venda, 150m²"); cy.get("[data-cy=list-container]") - .find("a") + .find("> div") .should("have.length", 20); }); it("click one item", function() { - cy.get("[data-cy=168c4f8d0a2e]").click(); + cy.get("[data-cy=168c4f8d0a2e]") + .find("[data-cy=link-detail]") + .click(); cy.url().should("include", "zap/168c4f8d0a2e"); }); it("contains text", function() { @@ -82,25 +84,25 @@ describe("test list all products", function() { cy.contains("900000"); }); it("contains slider", function() { - cy.get("#slider-slides") + cy.get(".slider-slides") .should("be.visible") .find("img") .should("have.length", 5); }); it("navigate slider", function() { - cy.get("#next").click(); + cy.get(".next").click(); cy.wait(300); - cy.get("#next").click(); + cy.get(".next").click(); cy.wait(300); - cy.get("#next").click(); + cy.get(".next").click(); cy.wait(300); - cy.get("#previous").click(); + cy.get(".previous").click(); cy.wait(300); - cy.get("#previous").click(); + cy.get(".previous").click(); cy.wait(300); - cy.get("#previous").click(); + cy.get(".previous").click(); cy.wait(300); - cy.get("#previous").click(); + cy.get(".previous").click(); }); }); }); diff --git a/src/App.js b/src/App.js index 42f8195..8813298 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,7 @@ import React from "react"; import { Switch, Route } from "react-router-dom"; import Home from "./components/Home"; -import ZapList from "./components/ZapList"; +import List from "./components/List"; import ZapItemDetail from "./components/ZapItemDetail"; import { css } from "glamor"; @@ -19,7 +19,7 @@ const App = () => (
- +
diff --git a/src/components/Card.js b/src/components/Card.js index 206bcc1..9825078 100644 --- a/src/components/Card.js +++ b/src/components/Card.js @@ -1,52 +1,134 @@ import React from "react"; +import Slider from "./Slider"; +import Text from "./Text"; +import { css } from "glamor"; +import Link from "./Link"; -const style = { - borderBottom: "1px solid gray" -}; - -const padding = { - padding: "10px", - minWidth: "150px", - display: "inline-block" +const styles = { + card: css({ + display: "grid", + gridTemplateColumns: "auto", + padding: 16, + margin: 25, + transition: ".3s", + backgroundColor: "whitesmoke", + "&:hover": { + boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2)" + }, + "> img": { + width: "100%" + }, + "@media(min-width: 570px)": { + gridTemplateColumns: "450px auto", + maxWidth: 1024, + margin: "25px auto" + } + }), + detail: css({ + display: "grid", + gridTemplateColumns: "auto", + padding: 16, + backgroundColor: "white", + maxWidth: 300, + margin: "0 auto", + "@media(min-width: 570px)": { + gridTemplateColumns: "450px auto", + maxWidth: 1024, + margin: "0 auto" + } + }), + link: css({ + display: "block", + textDecoration: "none", + transition: 0.1, + color: "green", + "&:after": { + content: "''", + display: "inline-block", + width: "100%", + borderBottom: "2px solid", + opacity: "0", + WebkitTransition: "opacity 0.35s, -webkit-transform 0.35s", + transition: "opacity 0.35s, transform 0.35s", + WebkitTransform: "scale(0,1)", + transform: "scale(0,1)" + }, + "&:hover": { + color: "black", + textShadow: "0 0 2px gainsboro", + "&:after": { + opacity: "1", + WebkitTransform: "scale(1)", + transform: "scale(1)" + } + } + }) }; function ZapItem(props) { var discount = 0; + var bathrooms = props.data.bathrooms; + var bedrooms = props.data.bedrooms; + var parkingSpaces = props.data.parkingSpaces; + var header = ""; + var businessType = props.data.pricingInfos.businessType; + var boundingBox = ""; + + // translate business type + businessType === "SALE" + ? (businessType = "à Venda") + : (businessType = "para Locação"); + header = "Apartamento " + businessType + ", " + props.data.usableAreas + "m²"; + + // plurals + bedrooms <= 1 ? (bedrooms += " Quarto | ") : (bedrooms += " Quartos | "); + bathrooms <= 1 + ? (bathrooms += " Banheiro | ") + : (bathrooms += " Banheiros | "); + parkingSpaces <= 1 ? (parkingSpaces += " Vaga") : (parkingSpaces += " Vagas"); + + // calculate bounding box if (props.data.pricingInfos.price) { discount = props.data.pricingInfos.price - props.data.pricingInfos.price * 0.1; } + + // show price with bounding box + props.boundinBoxZap + ? (boundingBox = "OFFER R$ " + discount.toLocaleString()) + : (boundingBox = "Fora do Bounding Box"); + + // return card return ( -
- - {props.data.id} - - - {props.data.pricingInfos.businessType - ? props.data.pricingInfos.businessType - : null} - - - price: - {props.data.pricingInfos.price ? props.data.pricingInfos.price : null} - - - discount: - {props.boundinBoxZap ? props.boundinBoxZap : null} - {props.boundinBoxZap ? " por: R$ " + discount : null} - - - lon: - {props.data.address.geoLocation.location.lon - ? props.data.address.geoLocation.location.lon - : null} - - - lat: - {props.data.address.geoLocation.location.lat - ? props.data.address.geoLocation.location.lat - : null} - +
+ +
+ + + + + + + +
); } diff --git a/src/components/Link.js b/src/components/Link.js new file mode 100644 index 0000000..9eb28c1 --- /dev/null +++ b/src/components/Link.js @@ -0,0 +1,34 @@ +import React from "react"; +import { css } from "glamor"; + +const styles = { + wrapper: css({ + display: "block" + }), + link: css({ + display: "inline-block", + margin: 10, + padding: "20px 30px", + fontSize: 16, + backgroundColor: "blue", + background: "linear-gradient(#0000FF, #0000CC)", + borderRadius: "4px", + color: "white", + cursor: "pointer", + textAlign: "center", + fontFamily: "Open Sans", + textDecoration: "none" + }) +}; + +function Link(props) { + return ( +
+ + {props.label} + +
+ ); +} + +export default Link; diff --git a/src/components/ZapList.js b/src/components/List.js similarity index 93% rename from src/components/ZapList.js rename to src/components/List.js index 73a0d99..9c177ba 100644 --- a/src/components/ZapList.js +++ b/src/components/List.js @@ -14,7 +14,7 @@ const boundinBoxZap = { maxlat: -23.546686 }; -class ZapList extends React.Component { +class List extends React.Component { constructor() { super(); @@ -142,13 +142,15 @@ var ProductList = props => { lat >= boundinBoxZap.minlat && lat <= boundinBoxZap.maxlat ) { - return ; + return ( + + ); } else { - return ; + return ; } })}
); }; -export default withRouter(ZapList); +export default withRouter(List); diff --git a/src/components/Slider.js b/src/components/Slider.js index a28fd1c..e452237 100644 --- a/src/components/Slider.js +++ b/src/components/Slider.js @@ -46,18 +46,18 @@ class Slider extends React.Component { } render() { return ( -
-
-
-
+
+
{this.props.images.map((slide, index) => { return ; })}
-
diff --git a/src/components/Text.js b/src/components/Text.js index 436ec5b..ecfb859 100644 --- a/src/components/Text.js +++ b/src/components/Text.js @@ -7,9 +7,9 @@ const styles = { margin: 10, fontWeight: 300, fontSize: 16, - lineHeight: 1.5, + lineHeight: 1, "> h1": { - fontSize: 24 + fontSize: 22 }, "> span": { fontSize: 20, @@ -30,7 +30,10 @@ function Text(props) { case "price": return (
- {props.label} + + {"R$ " + + props.label.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")} +
); default: diff --git a/src/components/__tests__/Card.test.js b/src/components/__tests__/Card.test.js index 5d7b910..3497ad5 100644 --- a/src/components/__tests__/Card.test.js +++ b/src/components/__tests__/Card.test.js @@ -4,7 +4,17 @@ import Card from "../Card"; const data = { id: 787654456, + parkingSpaces: 1, + images: [ + "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/285805119ab0761500127aebd8ab0e1d.jpg", + "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/4af1656b66b9e12efff6ce06f51926f6.jpg", + "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/895f0d4ce1e641fd5c3aad48eff83ac8.jpg", + "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/e7b5cce2d9aee78867328dfa0a7ba4c6.jpg", + "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/d833da4cdf6b25b7acf3ae0710d3286d.jpg" + ], address: { + city: "São Paulo", + neighborhood: "Brooklin", geoLocation: { location: { lon: -46.787, @@ -12,8 +22,13 @@ const data = { } } }, + bathrooms: 2, + bedrooms: 3, pricingInfos: { - price: 42000 + yearlyIptu: "0", + price: "405000", + businessType: "SALE", + monthlyCondoFee: "495" } }; diff --git a/src/components/__tests__/ZapList.test.js b/src/components/__tests__/List.test.js similarity index 83% rename from src/components/__tests__/ZapList.test.js rename to src/components/__tests__/List.test.js index 42067e8..b3f11a1 100644 --- a/src/components/__tests__/ZapList.test.js +++ b/src/components/__tests__/List.test.js @@ -1,6 +1,6 @@ import React from "react"; import createRouterContext from "react-router-test-context"; -import ZapList from "../ZapList"; +import List from "../List"; import { Switch, Route } from "react-router-dom"; import { shallow } from "enzyme"; @@ -8,7 +8,7 @@ it("renders /zap", () => { const context = createRouterContext({ location: { pathname: "/zap" } }); const wrapper = shallow( - + , { context } ); diff --git a/src/components/slider.css b/src/components/slider.css index f65be03..c6b4975 100644 --- a/src/components/slider.css +++ b/src/components/slider.css @@ -1,4 +1,4 @@ -#slider-container { +.slider-container { width: 400px; height: 300px; overflow: hidden; @@ -6,27 +6,28 @@ } .nav { z-index: 1; - padding: 10px; + background-color: rgba(255, 255, 255, 0.5); + padding: 10px 0; cursor: pointer; top: 50%; position: absolute; } -#previous { +.previous { transform: translateY(-50%); } -#next { - transform: translateY(-50%) translateX(330px); +.next { + transform: translateY(-50%) translateX(360px); } .nav img { width: 40px; height: 40px; } -#slider { +.slider { width: 400px; height: 300px; overflow: hidden; } -#slider-slides { +.slider-slides { transition: transform 0.5s ease-in-out; width: 2000px; } diff --git a/src/stories/index.js b/src/stories/index.js index b5eade4..9c697a2 100644 --- a/src/stories/index.js +++ b/src/stories/index.js @@ -8,10 +8,18 @@ import Text from "../components/Text"; import Image from "../components/Image"; import Button from "../components/Button"; import Slider from "../components/Slider"; +import Link from "../components/Link"; const data = { textLabel: "My Sample Text", + usableAreas: 69, + listingType: "USED", + createdAt: "2016-11-16T04:14:02Z", + listingStatus: "ACTIVE", id: 787654456, + parkingSpaces: 1, + updatedAt: "2016-11-16T04:14:02Z", + owner: false, images: [ "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/285805119ab0761500127aebd8ab0e1d.jpg", "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/4af1656b66b9e12efff6ce06f51926f6.jpg", @@ -20,15 +28,23 @@ const data = { "https://resizedimgs.vivareal.com/crop/400x300/vr.images.sp/d833da4cdf6b25b7acf3ae0710d3286d.jpg" ], address: { + city: "São Paulo", + neighborhood: "Brooklin", geoLocation: { + precision: "ROOFTOP", location: { - lon: -46.787, - lat: -46.897 + lon: -46.716542, + lat: -23.502555 } } }, + bathrooms: 2, + bedrooms: 3, pricingInfos: { - price: 42000 + yearlyIptu: "0", + price: "405000", + businessType: "SALE", + monthlyCondoFee: "495" } }; @@ -55,3 +71,4 @@ storiesOf("Button", module).add("default Button", () => ( storiesOf("Slider", module).add("default Slider", () => ( )); +storiesOf("Link", module).add("default Link", () => );