Home > Enterprise >  className of "bg-danger" is always applied to the Card even if the condition is not gettin
className of "bg-danger" is always applied to the Card even if the condition is not gettin

Time:05-06

I am working on this budget-app. Here the className = "bg-danger","bg-opacity-10" should only get applied if the "amount" is greater than "max". (amount > max) But here this class is always applied to the div.

App.js

import React from 'react'
import './App.css'
import { Container, Stack, Button } from 'react-bootstrap'
import BudgetCard from './components/BudgetCard'

function App() {
  return (
    <Container className="my-4">
      <Stack direction="horizontal" gap={2} className="mb-4">
        <h1 className="me-auto">Budgets</h1>
        <Button variant="primary">Add Budget</Button>
        <Button variant="outline-primary">Add Expenses</Button>
      </Stack>
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fill,minmax(300px,1fr))',
          gap: '1rem',
          alignItems: 'flex-start',
        }}
      >
        <BudgetCard name="Entertainment" gray amount="40" max="1000" />
      </div>
    </Container>
  )
}

export default App

BudgetCard.js

import { Button } from 'react-bootstrap'
import { Card, ProgressBar, Stack } from 'react-bootstrap'
import { currencyFormatter } from '../utils'

export default function BudgetCard({ name, amount, max, gray }) {
  const classNames = []
  if (amount > max) {
    classNames.push('bg-danger', 'bg-opacity-10')
  } else if (gray) {
    classNames.push('bg-light')
  }
  return (
    <Card className={classNames.join(' ')}>
      <Card.Body>
        <Card.Title className="d-flex justify-content-between align-items-baseline mb-3">
          <div className="me-2">{name}</div>
          <div className="d-flex align-items-baseline">
            {currencyFormatter.format(amount)}{' '}
            <span className="text-muted fs-6 ms-1">
              {' '}
              / {currencyFormatter.format(max)}
            </span>
          </div>
        </Card.Title>
        <ProgressBar
          className="rounded-pill"
          variant={getVariant(amount, max)}
          min={0}
          max={max}
          now={amount}
        />
        <Stack direction="horizontal" gap="2" className="mt-4">
          <Button variant="outline-primary" className="ms-auto">
            Add Expenses
          </Button>
          <Button variant="outline-secondary">View Expenses</Button>
        </Stack>
      </Card.Body>
    </Card>
  )
}

function getVariant(amount, max) {
  let ratio = amount / max
  if (ratio < 0.5) return 'primary'
  if (ratio < 0.75) return 'warning'
  return 'danger'
}

Here's the full code. Please find the image of the output for reference. Screenshot of JS REPL of above paragraph

  • Related