I'm doing a tutorial for a basic CRUD app with React and Tailwind, this is my first time setting it up and I'm trying to display a navbar but when i run 'npm run start', the output is blank. Can anyone guide me as to why? Following this: https://www.unimedia.tech/2021/11/30/build-a-simple-crud-app-using-react-and-node/
App.js
import React from "react";
import { Link } from "react-router-dom";
export default function Navigate(){
return (
<nav class="flex items-center justify-between flex-wrap bg-green-500 p-6">
<div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl tracking-tight">REACT CRUD APP</span>
</div>
<Link to="/">
<button class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-green-500 hover:bg-white mt-4 lg:mt-0">
HOME
</button>
</Link>
</nav>
)
}
tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Navigate.js
import React from "react";
export default function Navigate(){
return (
<nav class="flex items-center justify-between flex-wrap bg-green-500 p-6">
<div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl tracking-tight">REACT CRUD APP</span>
</div>
<div>
<button class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-green-500 hover:bg-white mt-4 lg:mt-0">
CREATE
</button>
</div>
</nav>
)
}
index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();
EDIT (New Output):
CHange your index.js file with this code. To work with Link you need to wrap your <App/> component with <BrowserRouter>. Also, it is best if you also add an output screenshot from the browser console as most of the time you will get detailed errors there.
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();
So I have not worked with react recently so I don't know if something might be changed in the new react-router-dom version, but I am sure you need to wrap your App component into <Router></Router> tags to render the <Link> tag.
Make changes in App.js as below and it will display your navbar.
import React from "react";
import { Link, BrowserRouter as Router } from "react-router-dom";
export default function Navigate() {
return (
<Router>
<nav class="flex items-center justify-between flex-wrap bg-green-500 p-6">
<div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl tracking-tight">
REACT CRUD APP
</span>
</div>
<Link to="/">
<button class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-green-500 hover:bg-white mt-4 lg:mt-0">
HOME
</button>
</Link>
</nav>
</Router>
);
Let me know if this solution works out.
Related
I have three components called blog cards that are rendered with an image and text. Depending on how long the text is the cards are of different heights. I want to render them, then get the tallest one, and sort of re-render them, so they are all the same height.
Here is the Page
import * as React from 'react'
import { SocialIconRow } from '#/components/social-icons'
import BlogPostCard from '#/components/BlogCard'
import Image from 'next/image'
import { useState, useEffect } from 'react'
import { FixedSizeList } from 'react-window'
function BlogPostCardsList({ cards }) {
const tallestCardHeight = useMemo(() => {
return Math.max(...cards.map(card => card.height))
}, [cards])
return (
<FixedSizeList
itemCount={cards.length}
itemSize={tallestCardHeight}
width={'100%'}
height={'100%'}
>
{({ index, style }) => <BlogPostCard style={style} {...cards[index]} />}
</FixedSizeList>
)
}
export default function MyComponent(props) {
const [cardHeight, setCardHeight] = useState(null);
const [maxHeight, setMaxHeight] = useState(0);
useEffect(() => {
const calculateHeight = () => {
const cards = document.querySelectorAll('.blog-post-card');
let heights = [];
cards.forEach(card => {
heights.push(card.clientHeight);
});
setMaxHeight(Math.max(...heights));
}
calculateHeight();
setCardHeight(maxHeight);
}, []);
return (
<>
<div className="container mx-auto flex flex-col">
<div className="container mx-auto flex">
<div className="w-1/2 pr-4">
<div className="text-4xl font-bold">Mike Borman</div>
<div className="text-lg mt-2">Writer, Content Creator and Developer on Cardano</div>
</div>
<div className="w-1/2 flex flex-col justify-center">
<div className="max-h-48 max-w-48 mx-auto my-auto">
<Image
src="/images/myfaceppgray.png"
alt="Picture of the author"
className="max-h-48 max-w-48"
width="150"
height="150"
unoptimized={true}
/>
</div>
<div className="mt-4">
<SocialIconRow className="social-icon-row" />
</div>
</div>
</div>
<div className="mt-8">
<div className="text-3xl font-bold">Featured Blogs</div>
<div className="grid grid-cols-3 gap-4 h-full mt-4 align-items-stretch">
<div style={{height: cardHeight}}>
<BlogPostCard
title="The Hydra Protocol Family — Scaling and Network Optimization for the Cardano Blockchain"
slug="the-hydra-protocol-family-scaling-and-network-optimization-for-the-cardano-blockchain"
imageslug="/images/hydra.png"
className="blog-post-card"
/>
</div>
<div style={{height: cardHeight}}>
<BlogPostCard
title="Ouroboros, A deep dive for non PhDs"
slug="ouroboros-a-deep-dive-for-non-phd"
imageslug="/images/ourobouros.png"
className="blog-post-card"
/>
</div>
<div className="h-full row-auto" style={{height: cardHeight}}>
<BlogPostCard
title="Ouroboros, A deep dive for non PhDs"
slug="ouroboros-a-deep-dive-for-non-phd"
imageslug="/images/ourobouros.png"
className="blog-post-card"
/>
</div>
</div>
</div>
</div>
</>
)
}
Here is the Card component:
import React from 'react'
import Link from 'next/link'
import Image from 'next/image'
function BlogPostCard(props) {
const { title, slug, imageslug } = props
return (
<Link href={`/blog/${slug}`}>
<a className="block flex flex-col justify-between rounded-md border-2 border-teal-400 transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
<img className="rounded-t-md h-48 w-full object-cover" src={imageslug} alt="blog post cover" />
<span className="text-white text-2xl p-4">{title}</span>
</a>
</Link>
)
}
export default BlogPostCard
I tried dynamically rendering them then setting them, btw I have no idea really what Im doing there.
You actually have all but one class already to do this entirely in CSS. Just add h-full to your a tag inside the BlogPostCard component's Link. Then you can get rid of all of the JS. Optionally, you could also remove the justify-between or change it to justify-stretch so that the titles of the blog posts are directly beneath of the post cover images.
In the demo below, you can see the result by clicking run code snippet. Also, if you're upgrading to NextJS 13, it's worth noting that you no longer need (and in fact can't have) an a tag as a child of Link. I'd suggest using article as I've done below, which will be more semantically correct anyway.
function BlogPage({posts}) {
return (
<main className="container mx-auto my-8">
<div className="flex gap-4">
<div className="w-1/2">
<h1 className="text-4xl font-bold">Mike Borman</h1>
<h2 className="text-lg mt-2">
Writer, Content Creator and Developer on Cardano
</h2>
</div>
<div className="w-1/2 flex flex-col justify-center items-center">
<span className="w-[150px] h-[150px] bg-neutral-300 rounded-full grid place-content-center">author img here</span>
<span>social row here</span>
</div>
</div>
<section className="mt-8">
<header>
<h2 className="text-3xl font-bold">Featured Blogs</h2>
</header>
<div className="grid grid-cols-3 gap-4 h-full mt-4 align-items-stretch">
{posts.map((post) => (
<BlogPostCard key={post.id} {...post} />
))}
</div>
</section>
</main>
)
}
function BlogPostCard({ slug, imageslug, title,}) {
return (
<Link href={`/blog/${slug}`}>
<article className="flex flex-col justify-stretch h-full rounded-md border-2 border-teal-400 bg-neutral-600 transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
<img
className="rounded-t-md h-48 w-full object-cover"
src={imageslug}
alt="blog post cover"
/>
<span className="text-white text-2xl p-4">{title}</span>
</article>
</Link>
)
}
/* Stubbing out next/link here since I can't run NextJS in code snippets */
function Link({ href, children, className }) {
return (
<a href={href} className={className}>
{children}
</a>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<BlogPage posts={[
{
id: 1,
title: 'The Hydra Protocol Family — Scaling and Network Optimization for the Cardano Blockchain',
slug: 'the-hydra-protocol-family-scaling-and-network-optimization-for-the-cardano-blockchain',
imageslug: 'https://d3lkc3n5th01x7.cloudfront.net/wp-content/uploads/2019/05/15233606/700-X-394.png',
},
{
id: 2,
title: 'Ouroboros, A deep dive for non PhDs',
slug: 'ouroboros-a-deep-dive-for-non-phd',
imageslug: 'https://www.almaviva.it/dam/jcr:6212e8ef-1ed6-40e2-a75f-b6fa7c814662/Blockchain_1280x720.jpg',
},
{
id: 3,
title: 'How Blockchain Is Used',
slug: 'how-blockchain-is-used',
imageslug: 'https://imageio.forbes.com/specials-images/imageserve/5f2a32ee3b52675a453e2881/Fascinating-Examples-Of-How-Blockchain-Is-Used-In-Insurance--Banking-And-Travel/960x0.jpg?format=jpg&width=960',
},
]} />
);
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>
So i gave made a login system, and it works fine, it's just that i try to only show my navbar after logging in, it worked at first, now it does not and i can't figure out why.
noder server.js
`
app.get("/login", (req, res)=> {
if (req.session.user) {
res.send({loggedIn: true, user: req.session.user})
}else{
res.send({loggedIn: false})
}
})
`
And here is the App.js where i try to see if they're logged in or not. If they are the menu should show, if not then it should not show.
`
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Axios from "axios";
import Button from "./Button"
import { Cookie } from "express-session";
const Navbar = () => {
const Links = [
{name: "Home", link: "/home"},
{name: "Profile", link: "/profile"},
{name: "Settings", link: "/settings"},
];
const [openMenu, setOpenMenu] = useState(false)
return(
<div className="shadow-md w-full fixed top-0 left-0">
<div className="md:flex items-center justify-between bg-gray-800 dark:text-white py-4 md:px-10 px-7">
<div className="font-bold text-2xl cursor-pointer flex items-center">
Alex' file server
</div>
<div onClick={()=> {setOpenMenu(!openMenu)}} className="text-3xl absolute right-8 top-6 cursor-pointer md:hidden transition-transform duration-500">
<ion-icon name={openMenu ? "close" : "menu"}></ion-icon>
</div>
<ul className={`md:flex md:items-center md:pb-0 pb-12 absolute md:static bg-gray-800 md:z-auto z-[-1] left-0 w-full md:w-auto md:pl-0 pl-9 transition-all duration-500 ease-in ${openMenu ? "top-10 opacity-100" : "top-[-490px] md:opacity-100 opacity-0"}`}>
{
Links.map((link)=> (
<li key={link.name} className="md:ml-8 text-xl md:my-0 my-7">
<Link to={link.link} className="hover:text-teal-300 duration-500">{link.name}</Link>
</li>
))
}
<Button>
Logout
</Button>
</ul>
</div>
</div>
)
}
export default Navbar
`
I have tried to validate within the navbar itself, but that does not make sense
I just try to hit the API when like and dislike button is clicked , but I get unauthorized error after passing the authorization header.
What is the solution of this problem. There is post where all users can like or dislike. There is only unauthorized error, everything is true.
This is the screenshot of where the action is written.
This is the screenshot where the error is displayed.
`JavaScript code
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import {Link} from 'react-router-dom';
import { deltePost, addLike, deleteLike } from
class PostItem extends Component {
onDelteClick(postId)
{
this.props.deltePost(postId);
}
onLikeClick(id)
{
this.props.addLike(id);
}
onunLikeClick(id)
{
this.props.deleteLike(id);
}
render() {
const {post,auth,showActions}=this.props;
return (
<section className="container">
<div className="posts">
<div className="post bg-white p-1 my-1">
<div>
<a href="profile.html">
<img
className="round-img"
src="//www.gravatar.com/avatar/05434e5d678bc30625550497804f6d0e?s=200&r=pg&d=mm"
alt=""
/>
<h4>{post.name}</h4>
</a>
</div>
<div>
<p className="my-1">
{post.text}
</p>
<p className="post-date">
{post.date}
</p>
{showActions ?(<span>
<button onClick={this.onLikeClick.bind(this, post._id)} type="button" className="btn btn-light">
<i className="fas fa-thumbs-up"></i>
<span>{post.likes.length}</span>
</button>
<button onClick={this.onunLikeClick.bind(this, post._id)} type="button" className="btn btn-light">
<i className="fas fa-thumbs-down"></i>
</button>
<Link to={`/post/${post._id}`} className="btn btn-primary">
Comments <span className='comment-count'>{post.comments.length}</span>
</Link>
{post.user === auth.user.id ?(
<button
type="button"
onClick={this.onDelteClick.bind(this,post._id)}
className="btn btn-danger"
>
<i className="fas fa-times"></i>
</button>
):null}
</span>) :null}
</div>
</div></div>
</section>
)
}
}
PostItem.defaultProps={
showActions:true
}
PostItem.propTypes={
deltePost:PropTypes.func.isRequired,
deleteLike:PropTypes.func.isRequired,
addLike:PropTypes.func.isRequired,
post:PropTypes.object.isRequired,
auth:PropTypes.object.isRequired
}
const mapStateToProps= state =>({
auth:state.auth
})
export default connect(mapStateToProps,{deltePost,addLike,deleteLike})(PostItem)
`
I'm using ReactJs to build a simple app with 3 routes:
"/" <- index.js
"/login" <- login.js
"/register" <- register.js
to view these pages correctly, i need to import CSS-files.
But if i import the CSS-file for the "/login" route, it also gets loaded in the "/" route.
here are my files:
app.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import './App.css';
import Index from './pages/index';
import Login from './pages/login';
import './css/bootstrap.css';
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path='/' component={Index} />
<Route exact path='/login' component={Login} />
</Switch>
</Router>
);
}
}
export default App;
index.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import logo from '../logo.svg';
import '../App.css';
class Index extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
<Link to={'/login'}>Login</Link>
</p>
</div>
);
}
}
export default Index;
and login.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import '../css/login.css';
import '../css/main.css';
import logo from '../img/s900x300.png';
import back from '../img/back.svg';
import view from '../img/view.svg';
export default class Login extends Component {
render() {
return (
<div>
<script async="" src="https://www.google-analytics.com/analytics.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<button className="back">
<a><img alt="" className="left" src={back}/></a>
</button>
<div className="background">
</div>
<div id="login" className="container login">
<img alt="" src={logo} />
<center><h5></h5></center>
<input name="user" type="text" required placeholder="Benutzername oder Email"/>
<div className="password">
<input name="pw" required maxLength="64" type="password" placeholder="Passwort"/>
<button id="view_toggle">
<img alt="" src={view}/>
</button></div>
<form>
<button id="login" className="on">Login</button>
</form>
<center><b><a>back</a> | <Link to={'/register'}><a>Create account</a></Link></b></center>
</div>
<script src="/js/bootstrap.min.js"></script>
</div>
);
}
}
for example: in my login.css want a background image for my body. but this background is also applied to "/". How can i prevent, that the css is used global? Sorry for my bad english :)
To avoid your issue, you can create a global css file like style.css
then you link it to your index.html
as #Chase DeAnda suggest you can establish namespace for each page.
your style.css should be something like
.login .myClass {...}
.login .anotherClass {...}
.main .myClass {...}
.main .anotherClass {...}
I'm creating a component with a background being provided as a its attribute, like this:
<overlay-card src="https://static.pexels.com/photos/51387/mount-everest-himalayas-nuptse-lhotse-51387.jpeg" color="rgba-bluegrey-strong">
My component template:
`<div class="card card-image mb-3" style="background-image: url({{src}});" [ngClass]="(alignment==='left')?'text-left':(alignment==='right')?'text-right':'text-center'">
<div class="text-white d-flex py-5 px-4 {{color}}"
>
<ng-content></ng-content></div>
</div>`
What I get is:
// WARNING: sanitizing unsafe style value background-image: url(https://static.pexels.com/photos/51387/mount-everest-himalayas-nuptse-lhotse-51387.jpeg); (see http://g.co/ng/security#xss).
As it's a <div>, I cannot really count on [ngSrc].
You can use ngStyle for that:
<div [ngStyle]="{'background-image': 'url(' + src + ')'}">...</div>
You should make this url trusted in your component code and a litle bit change you component template like this:
import {DomSanitizer} from '#angular/platform-browser';
...
export class OverlayCard {
#Input() src: string;
constructor(private sanitizer: DomSanitizer) {
this.trustedSrc = sanitizer.bypassSecurityTrustUrl(this.src);
}
<div class="card card-image mb-3" style="background-image: url({{trustedSrc}});" [ngClass]="(alignment==='left')?'text-left':(alignment==='right')?'text-right':'text-center'">
<div class="text-white d-flex py-5 px-4 {{color}}">
<ng-content></ng-content>
</div>
</div>