Compare commits

...

10 Commits

Author SHA1 Message Date
ada2e1cb72 Add optional URL to Product type and update Link component
Updated the `Product` type in `product-service.ts` to include an optional `url` property. Modified the `Link` component in `product-item.tsx` to use this new `url` for navigation, defaulting to '/404' if not provided. This enhances product item display by making product names clickable.
2025-07-03 09:14:49 +02:00
786c9e13f0 Rename getProducts to getProductsAsync for clarity
Updated the `getProducts` function in `product-service.ts` to `getProductsAsync` to reflect its asynchronous nature. Adjusted the import in `products-view.tsx` accordingly and modified the `useEffect` hook in `ProductsView` to utilize the new function, ensuring proper handling of asynchronous requests.
2025-07-02 17:07:57 +02:00
0acdfdb1eb Update Product type and enhance ProductItem component
Modified the `Product` type to make `status` and `coverUrl` optional, and added a new `version` property for improved flexibility. Updated the `getProducts` function to reflect these changes. In the `ProductItem` component, added a new `Label` to display the product's version and ensured a default image is used if `coverUrl` is not provided. Updated rendering logic to conditionally show both status and version.
2025-07-02 17:07:06 +02:00
3d49f32175 Make Product properties optional and improve safety
Updated the `Product` type in `product-service.ts` to make `price`, `colors`, and `priceSale` optional. Removed hardcoded values from the `getProducts` function, allowing for more flexible product creation. Enhanced the `ProductItem` component to safely access the `colors` property using optional chaining, defaulting to an empty array if undefined.
2025-07-02 16:11:55 +02:00
3be5cba323 Refactor product data types and update components
Replaced `ProductItemProps` with a new `Product` type in `product-service.ts`, which includes properties like `id`, `name`, `price`, `status`, and `coverUrl`. Updated the `getProducts` function to return `Promise<Product[]>` instead of `Promise<ProductItemProps[]>`. Modified the `ProductItem` component in `product-item.tsx` to accept the new `Product` type. Adjusted `products-view.tsx` to import `Product` and manage the state as `Array<Product>`.
2025-07-02 15:59:34 +02:00
b7c5734a1b Refactor ProductItemProps type definition
Moved `ProductItemProps` from `product-item.tsx` to `product-service.ts` for centralized access. Updated `product-item.tsx` to import the type from the new location. Adjusted imports in `products-view.tsx` to streamline dependencies and reduce redundancy. This improves code organization and maintains a single source of truth for the `ProductItemProps` type.
2025-07-02 15:45:44 +02:00
a155c991c6 Add product fetching functionality to ProductsView
Updated `products-view.tsx` to use `useEffect` for fetching products from an API and manage them with a new state variable. Modified rendering logic to display fetched products instead of a mocked list.

Created/modified `product-service.ts` to include the `getProducts` function, simulating an API call that returns an array of product objects.
2025-07-02 15:38:27 +02:00
b6ffdaf03f Update image source for digital data icon
Modified the `src` attribute of an `<img>` element in `app.tsx` to replace the previous image with a new icon located at "/assets/images/dd-button-icon.webp". This change enhances the visual representation of the application by using a more relevant image.
2025-07-02 11:45:44 +02:00
325b27262e Add floating action button to App component
Updated the `App` component in `app.tsx` to include a new floating action button (Fab) linking to Digital Data. The button now features a transparent background and no box shadow, along with an image for improved visual representation. The `useScrollToTop` function remains unchanged but has a more streamlined implementation.
2025-07-02 11:16:26 +02:00
8771e025bc Standardproduktbild hinzugefügt und mit useState konfiguriert. 2025-07-02 11:05:16 +02:00
30 changed files with 84 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

View File

@@ -0,0 +1,31 @@
export type Product = {
id: string;
name: string;
price?: number;
status?: string;
version?: string;
coverUrl?: string;
colors?: string[];
priceSale?: number;
url?: string;
};
/**
* send a request to the server to get the products
* @returns Array of products
*/
export function getProductsAsync(): Promise<Product[]> {
//TODO: Implement the API call using fetch or axios
return Promise.resolve([
{
id: '1',
name: "User Manager",
version: "1.0.0"
},
{
id: '2',
name: "Envelope Generator",
version: "1.0.0"
}
]);
}

View File

@@ -19,11 +19,12 @@ type AppProps = {
export default function App({ children }: AppProps) {
useScrollToTop();
const githubButton = () => (
const ddButton = () => (
<Fab
size="medium"
aria-label="Github"
href="https://github.com/minimal-ui-kit/material-kit-react"
aria-label="Digital Data"
href="https://digitaldata.works/"
target="_blank"
sx={{
zIndex: 9,
right: 20,
@@ -31,17 +32,21 @@ export default function App({ children }: AppProps) {
width: 48,
height: 48,
position: 'fixed',
bgcolor: 'grey.800',
bgcolor: 'transparent',
boxShadow: 'none'
}}
>
<Iconify width={24} icon="socials:github" sx={{ '--color': 'white' }} />
<img
src="/assets/images/dd-button-icon.webp"
alt="Digital Data"
/>
</Fab>
);
return (
<ThemeProvider>
{children}
{githubButton()}
{ddButton()}
</ThemeProvider>
);
}
@@ -56,4 +61,4 @@ function useScrollToTop() {
}, [pathname]);
return null;
}
}

View File

@@ -1,3 +1,5 @@
import { useState } from 'react';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import Card from '@mui/material/Card';
@@ -6,22 +8,15 @@ import Typography from '@mui/material/Typography';
import { fCurrency } from 'src/utils/format-number';
import { Product } from 'src/api/product-service';
import { Label } from 'src/components/label';
import { ColorPreview } from 'src/components/color-utils';
// ----------------------------------------------------------------------
export type ProductItemProps = {
id: string;
name: string;
price: number;
status: string;
coverUrl: string;
colors: string[];
priceSale: number | null;
};
export function ProductItem({ product }: { product: ProductItemProps }) {
// TODO: Add explanation part
export function ProductItem({ product }: { product: Product }) {
const renderStatus = (
<Label
variant="inverted"
@@ -38,11 +33,30 @@ export function ProductItem({ product }: { product: ProductItemProps }) {
</Label>
);
const renderVersion = (
<Label
variant="inverted"
color='info'
sx={{
zIndex: 9,
top: 16,
right: 16,
position: 'absolute',
textTransform: 'uppercase',
}}
>
{product.version}
</Label>
);
const [imgSrc, setImgSrc] = useState(product.coverUrl ?? "/assets/images/product/product-default.webp");
const renderImg = (
<Box
component="img"
alt={product.name}
src={product.coverUrl}
src={imgSrc}
onError={() => setImgSrc('/assets/images/product/product-default.webp')}
sx={{
top: 0,
width: 1,
@@ -74,11 +88,12 @@ export function ProductItem({ product }: { product: ProductItemProps }) {
<Card>
<Box sx={{ pt: '100%', position: 'relative' }}>
{product.status && renderStatus}
{product.version && renderVersion}
{renderImg}
</Box>
<Stack spacing={2} sx={{ p: 3 }}>
<Link color="inherit" underline="hover" variant="subtitle2" noWrap>
<Link color="inherit" underline="hover" variant="subtitle2" noWrap target="_blank" href={product.url ?? '/404'}>
{product.name}
</Link>
@@ -89,7 +104,7 @@ export function ProductItem({ product }: { product: ProductItemProps }) {
justifyContent: 'space-between',
}}
>
<ColorPreview colors={product.colors} />
<ColorPreview colors={product?.colors ?? []} />
{renderPrice}
</Box>
</Stack>

View File

@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useState, useCallback, useEffect } from 'react';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
@@ -7,9 +7,10 @@ import Typography from '@mui/material/Typography';
import { _products } from 'src/_mock';
import { DashboardContent } from 'src/layouts/dashboard';
import { getProductsAsync, Product } from 'src/api/product-service';
import { ProductItem } from '../product-item';
import { ProductSort } from '../product-sort';
import { ProductItem } from '../product-item';
import { CartIcon } from '../product-cart-widget';
import { ProductFilters } from '../product-filters';
@@ -64,6 +65,8 @@ export function ProductsView() {
const [filters, setFilters] = useState<FiltersProps>(defaultFilters);
const [products, setProducts] = useState<Array<Product>>([]);
const handleOpenFilter = useCallback(() => {
setOpenFilter(true);
}, []);
@@ -84,6 +87,12 @@ export function ProductsView() {
(key) => filters[key as keyof FiltersProps] !== defaultFilters[key as keyof FiltersProps]
);
useEffect(() => {
getProductsAsync().then((res) => {
setProducts(res);
});
}, []);
return (
<DashboardContent>
<CartIcon totalItems={8} />
@@ -139,7 +148,7 @@ export function ProductsView() {
</Box>
<Grid container spacing={3}>
{_products.map((product) => (
{products.map((product) => (
<Grid key={product.id} size={{ xs: 12, sm: 6, md: 3 }}>
<ProductItem product={product} />
</Grid>