I've been making a website to showcase my personal photography, and I've been getting my photos from Google Photos, using their features. (There's a medium post on how to do this)!
However, one problem I have been having is with scaling. I would like my images to be as quality as possible but also at a small enough size for them to fit into a grid on my page. However, when I use the built in parameters to do this (according to the docs) scaling is not preserved!
Example:
My page's code is as follows:
const axios = require('axios');
const Image = require('next/image');
const _ = require('lodash');
export default function Home({ pictures }) {
return (
<div>
<div className="hero min-h-screen" style={{ backgroundImage: 'url(https://lh3.googleusercontent.com/wwilPCF5L98Osl7_HVohVi34EP4SHUNKbxCe-fBooyNcTdvAWawcP3paqGxvAW3gCzXBl4aQOT_oxwYuXXaMG3ICM7cOkWJH6eYcozUqr9agShnjQu8kWFsPxtL7WD7H5sF5rkR9Vdk=w2048)' }}>
<div className="hero-overlay bg-opacity-60" />
<div className="hero-content text-center text-neutral-content">
<div className="max-w-md">
<h1 className="mb-5 text-5xl font-bold">Photography</h1>
<p className="mb-5">Aside from programming, I also love photography! </p>
</div>
</div>
</div>
<div className="flex flex-col flex-wrap m-10">
<div className="flex flex-row basis-1 flex-wrap m-4">
{
pictures.map(((x) => (
<img src={`${x}`} alt="Hello." key={`${x}?`} className=" flex-col flex-auto m-3 rounded-md shadow-md" />
)))
}
</div>
</div>
</div>
);
}
export async function getServerSideProps({ req, res }) {
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
const regex = /\["(https:\/\/lh3\.googleusercontent\.com\/[a-zA-Z0-9\-_]*)"/g;
function extractPhotos(content) {
const links = new Set();
let match;
while (match = regex.exec(content)) {
links.add(match[1]);
}
return Array.from(links);
}
async function getAlbum(id) {
const response = await axios.get(`https://photos.app.goo.gl/${id}`);
const photos = _.shuffle(extractPhotos(response.data));
return photos;
}
const pictures = await getAlbum('ZbGaHdrs62q5Jyrk8');
return {
props: { pictures }, // will be passed to the page component as props
};
}
How can I ensure the images are properly scaled? Is this even possible? Will I need some CSS trick? Thanks!
Related
I am creating a directory of users in Next.js. The users are stored in Supabase. I need for all the users to be displayed in the index.js file, looping through them and showing them on a grid. This is working with getStaticProps, fetching the data and passing it as props profiles.
However, when clicking on each profile, it does redirect me to the [id].js page, but it appends /undefined to the url, rather than the id.
My file tree looks as follows:
pages
people
index.js
[id].js
export default function People({ profiles }) {
return (
<div className="body min-h-[90vh]">
<Head>
<title>People</title>
<link rel="icon" href="/logo" />
</Head>
<div
key={profiles.id}
profiles={profiles}
className="flex flex-col items-center py-16"
>
<div className="grid md:grid-flow-col md:grid-cols-3 xl:grid-cols-4 gap-8 lg:gap-12">
{profiles.map((profile) => (
<Link href={`/people/${profiles.id}`} key={profiles.id}>
<div
profile={profile}
id={profile.id}
className="flex flex-col w-full justify-center items-center p-8 shadow-md hover:shadow-lg"
>
{profile.avatar_url && (
<Image
src={profile.avatar_url}
alt="profile picture"
width={200}
height={200}
className="rounded-full"
object-fit="cover"
/>
)}
<h1 className="text-2xl pt-8 text-center">
{profile.full_name}
</h1>
<p>{profile.skills.skill}</p>
<button className="button w-full">See lessons</button>
</div>
</Link>
))}
</div>
</div>
</div>
);
}
export async function getStaticProps() {
const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL || "",
process.env.SUPABASE_SERVICE_ROLE_KEY || ""
);
const { data } = await supabaseAdmin
.from("profiles")
.select("*, skills(skill)")
.order("id");
console.log(data);
return {
props: {
profiles: data,
},
};
}
Any ideas as to what I am doing wrong are highly appreciated.
Thanks.
<div class="mysel">
<button class="btn"></button>
<div class="iconName">James</div>
</div>
<div class="mysel">
<button class="btn"></button>
<div class="iconName">John</div>
</div>
I want to click the button by codition of James
so I try to use selector by this
page.locator('button:right-of(:text("james")').click();
but fail
how I could choice the button by txt in the next div?
There's not much context to work from here, and the -of selectors seem dependent on CSS/layout information I don't have, but selecting based on .mysel's text works for your example:
const playwright = require("playwright"); // ^1.28.1
const html = `
<div class="mysel">
<button class="btn">GOT IT</button>
<div class="iconName">James</div>
</div>
<div class="mysel">
<button class="btn"></button>
<div class="iconName">John</div>
</div>
`;
let browser;
(async () => {
browser = await playwright.chromium.launch();
const page = await browser.newPage();
await page.setContent(html);
const sel = '.mysel:has(:text("james")) button';
console.log(await page.locator(sel).textContent()); // => GOT IT
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
'.mysel:has(.iconName:text("james")) .btn' is also possible in case there are other elements and you need to be more specific.
I am using Tailwind CSS with next.js.
I have 8 images of different sizes and want to keep 4 images in a row for mid and large-size devices and 2 images in a row for small-size devices.
I want to give equal space between the items in a row but I want the first item in a row to be at the leftmost place and the last item in a row to be at the rightmost place.
The rest of the items should maintain equal distance between them.
How can I achieve this using Tailwind CSS? Normally with some conditions, I know how to do it, but is there any way to do it directly with Tailwind?
JSON response from API:
const ourPartners = [
{
id: "partner01",
pic: partner_01
},
{
id: "partner02",
pic: partner_02,
},
{
id: "partner03",
pic: partner_03,
},
{
id: "partner04",
pic: partner_04,
},
{
id: "partner05",
pic: partner_05,
},
{
id: "partner06",
pic: partner_06,
},
{
id: "partner07",
pic: partner_07,
},
{
id: "partner08",
pic: partner_08,
}
]
The code where I'm mapping over the array:
<div className="flex flex-row flex-wrap justify-between items-center">
{
ourPartners.map((item, index) => {
return (
<div className={`md:w-1/4 w-1/2 mb-10 ${(index % 4 !== 0 ? ('flex justify-center') : ('flex justify-start'))}`} key={item.id}>
<div className="w-32 object-contain">
<Image
alt="partner"
width="auto"
height="auto"
src={item.pic}
quality={100}
/>
</div>
</div>
)
})
}
</div>
EDITED:
I actually learned something new here too. You can use nth-child now with Tailwind.
const Partners = () => {
return (
<div className="grid md:grid-cols-4 grid-cols-2 gap-y-10 justify-between">
{ourPartners.map((item, index) => {
return (
<div
key={item.id}
className="odd:justify-self-start even:justify-self-end md:[&:nth-child(4n+2)]:justify-self-center md:[&:nth-child(4n+3)]:justify-self-center"
>
<div className="w-32">
<img alt="partner" width="auto" height="auto" src={item.pic} />
</div>
</div>
);
})}
</div>
);
};
export default Partners;
// I am trying to print out the database elements to react typescript home page, but when i print // it out it prints out
// [Object] [Object].
function HomePage(){
const [games, setGames] = useState< IGame []>([]);
useEffect(() => {
GameService.GetAllGames().then((data) => setGames(data));
}, []);
function onClickCreateADivWithGamesInfromation(){
const div = document.createElement('div');
const informationAboutGames = document.createElement('information');
informationAboutGames.innerText = `
${games.map((game, index) => {
return <GamesItem key={index} {...game} />
})}`;
JSON.stringify(informationAboutGames);
div.appendChild(informationAboutGames);
document.body.appendChild(div);
}
return(
<div>
<header>
<h1 className='text-center mb-5 '>Electric games</h1>
</header>
<br />
<main>
<div className='text-center'>
<h3 className='text-center'>Show all games</h3>
<button className='btn btn-primary' onClick={onClickCreateADivWithGamesInfromation} >Show all</button>
</div>
while searching, the results should appear as a div like below :
i use jquery to search in table,how to get the result like above.
my component code is:
<div id="modaldash" style={{ display: (searching ? 'block' : 'none') }}>
<p className="font-weight-medium" id="name"> <img id="logo" className="logo" src={jessica} alt="pam-logo" /> Jessica James </p>
<button id="Addlist" onClick={this.onSubmitdata} className="btn info">{this.state.shown ? "Addded" : "Add to list"}</button>
<p id="mailid">jessicajames#gmail.com </p>
<p id= "address">Mountain view,Ave</p>
</div>
its just a static content for css. how to use search and get results like above.
export default function App() {
// considering the data object to search on name
const [searchedData, setSearchedData] = useState([]);
const users = [
{
name: "abc1",
emailid: "abc1#gmail.com",
address: "23rd main, 2nd street"
},
{
name: "adb2",
emailid: "abc2#gmail.com",
address: "23rd main, 2nd street"
},
{
name: "adc3",
emailid: "abc3#gmail.com",
address: "23rd main, 2nd street"
}
];
const handleSearch = event => {
const data = users.filter(
user => user.name.indexOf(event.target.value) !== -1
);
setSearchedData(data);
};
const showSearchedData = () => {
return searchedData.map(user => (
<div key={user.emailid}>
<p className="font-weight-medium" id="name">
{" "}
<img id="logo" className="logo" src="" alt="pam-logo" />
{user.name}
</p>
<button id="Addlist"> Added/ add to list</button>
<p id="mailid">{user.emailid} </p>
<p id="address">{user.address}</p>
</div>
));
};
return (
<div className="App">
<input type="text" onChange={handleSearch} />
<div id="modaldash">{searchedData.length > 0 && showSearchedData()}</div>
</div>
);
}
You can add CSS to make a look and feel like shown in image attached.
Check the working example here https://codesandbox.io/s/falling-sun-r3rim