diff --git a/.snapshots/config.json b/.snapshots/config.json new file mode 100644 index 00000000..dfadca27 --- /dev/null +++ b/.snapshots/config.json @@ -0,0 +1,151 @@ +{ + "excluded_patterns": [ + ".git", + ".gitignore", + "gradle", + "gradlew", + "gradlew.*", + "node_modules", + ".snapshots", + ".idea", + ".vscode", + "*.log", + "*.tmp", + "target", + "dist", + "build", + ".DS_Store", + "*.bak", + "*.swp", + "*.swo", + "*.lock", + "*.iml", + "coverage", + "*.min.js", + "*.min.css", + "__pycache__", + ".marketing", + ".env", + ".env.*", + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.bmp", + "*.tiff", + "*.ico", + "*.svg", + "*.webp", + "*.psd", + "*.ai", + "*.eps", + "*.indd", + "*.raw", + "*.cr2", + "*.nef", + "*.mp4", + "*.mov", + "*.avi", + "*.wmv", + "*.flv", + "*.mkv", + "*.webm", + "*.m4v", + "*.wfp", + "*.prproj", + "*.aep", + "*.psb", + "*.xcf", + "*.sketch", + "*.fig", + "*.xd", + "*.db", + "*.sqlite", + "*.sqlite3", + "*.mdb", + "*.accdb", + "*.frm", + "*.myd", + "*.myi", + "*.ibd", + "*.dbf", + "*.rdb", + "*.aof", + "*.pdb", + "*.sdb", + "*.s3db", + "*.ddb", + "*.db-shm", + "*.db-wal", + "*.sqlitedb", + "*.sql.gz", + "*.bak.sql", + "dump.sql", + "dump.rdb", + "*.vsix", + "*.jar", + "*.war", + "*.ear", + "*.zip", + "*.tar", + "*.tar.gz", + "*.tgz", + "*.rar", + "*.7z", + "*.exe", + "*.dll", + "*.so", + "*.dylib", + "*.app", + "*.dmg", + "*.iso", + "*.msi", + "*.deb", + "*.rpm", + "*.apk", + "*.aab", + "*.ipa", + "*.pkg", + "*.nupkg", + "*.snap", + "*.whl", + "*.gem", + "*.pyc", + "*.pyo", + "*.pyd", + "*.class", + "*.o", + "*.obj", + "*.lib", + "*.a", + "*.map", + ".npmrc" + ], + "default": { + "default_prompt": "Enter your prompt here", + "default_include_all_files": false, + "default_include_entire_project_structure": true + }, + "included_patterns": [ + "build.gradle", + "settings.gradle", + "gradle.properties", + "pom.xml", + "Makefile", + "CMakeLists.txt", + "package.json", + "requirements.txt", + "Pipfile", + "Gemfile", + "composer.json", + ".editorconfig", + ".eslintrc.json", + ".eslintrc.js", + ".prettierrc", + ".babelrc", + ".dockerignore", + ".gitattributes", + ".stylelintrc", + ".npmrc" + ] +} \ No newline at end of file diff --git a/.snapshots/readme.md b/.snapshots/readme.md new file mode 100644 index 00000000..21fa917d --- /dev/null +++ b/.snapshots/readme.md @@ -0,0 +1,11 @@ +# Snapshots Directory + +This directory contains snapshots of your code for AI interactions. Each snapshot is a markdown file that includes relevant code context and project structure information. + +## What's included in snapshots? +- Selected code files and their contents +- Project structure (if enabled) +- Your prompt/question for the AI + +## Configuration +You can customize snapshot behavior in `config.json`. diff --git a/.snapshots/sponsors.md b/.snapshots/sponsors.md new file mode 100644 index 00000000..2df337f4 --- /dev/null +++ b/.snapshots/sponsors.md @@ -0,0 +1,44 @@ +# Thank you for using Snapshots for AI + +Thanks for using Snapshots for AI. We hope this tool has helped you solve a problem or two. + +If you would like to support our work, please help us by considering the following offers and requests: + +## Ways to Support + +### Join the GBTI Network!!! 🙏🙏🙏 +The GBTI Network is a community of developers who are passionate about open source and community-driven development. Members enjoy access to exclussive tools, resources, a private MineCraft server, a listing in our members directory, co-op opportunities and more. + +- Support our work by becoming a [GBTI Network member](https://gbti.network/membership/). + +### Try out BugHerd 🐛 +BugHerd is a visual feedback and bug-tracking tool designed to streamline website development by enabling users to pin feedback directly onto web pages. This approach facilitates clear communication among clients, designers, developers, and project managers. + +- Start your free trial with [BugHerd](https://partners.bugherd.com/55z6c8az8rvr) today. + +### Hire Developers from Codeable 👥 +Codeable connects you with top-tier professionals skilled in frameworks and technologies such as Laravel, React, Django, Node, Vue.js, Angular, Ruby on Rails, and Node.js. Don't let the WordPress focus discourage you. Codeable experts do it all. + +- Visit [Codeable](https://www.codeable.io/developers/?ref=z8h3e) to hire your next team member. + +### Lead positive reviews on our marketplace listing ⭐⭐⭐⭐⭐ +- Rate us on [VSCode marketplace](https://marketplace.visualstudio.com/items?itemName=GBTI.snapshots-for-ai) +- Review us on [Cursor marketplace](https://open-vsx.org/extension/GBTI/snapshots-for-ai) + +### Star Our GitHub Repository ⭐ +- Star and watch our [repository](https://github.com/gbti-network/vscode-snapshots-for-ai) + +### 📡 Stay Connected +Follow us on your favorite platforms for updates, news, and community discussions: +- **[Twitter/X](https://twitter.com/gbti_network)** +- **[GitHub](https://github.com/gbti-network)** +- **[YouTube](https://www.youtube.com/channel/UCh4FjB6r4oWQW-QFiwqv-UA)** +- **[Dev.to](https://dev.to/gbti)** +- **[Daily.dev](https://dly.to/zfCriM6JfRF)** +- **[Hashnode](https://gbti.hashnode.dev/)** +- **[Discord Community](https://gbti.network)** +- **[Reddit Community](https://www.reddit.com/r/GBTI_network)** + +--- + +Thank you for supporting open source software! 🙏 diff --git a/app/(main)/pages/crud/page.tsx b/app/(main)/pages/crud/page.tsx index 52cf6e5e..beaf669d 100644 --- a/app/(main)/pages/crud/page.tsx +++ b/app/(main)/pages/crud/page.tsx @@ -2,18 +2,26 @@ 'use client'; import { Button } from 'primereact/button'; import { Column } from 'primereact/column'; -import { DataTable } from 'primereact/datatable'; +import { DataTable, DataTableFilterMeta } from 'primereact/datatable'; import { Dialog } from 'primereact/dialog'; +import { Dropdown } from 'primereact/dropdown'; import { FileUpload } from 'primereact/fileupload'; +import { FilterMatchMode, FilterOperator } from 'primereact/api'; import { InputNumber, InputNumberValueChangeEvent } from 'primereact/inputnumber'; import { InputText } from 'primereact/inputtext'; import { InputTextarea } from 'primereact/inputtextarea'; +import { MultiSelect } from 'primereact/multiselect'; import { RadioButton, RadioButtonChangeEvent } from 'primereact/radiobutton'; import { Rating } from 'primereact/rating'; +import { Skeleton } from 'primereact/skeleton'; +import { Tag } from 'primereact/tag'; import { Toast } from 'primereact/toast'; import { Toolbar } from 'primereact/toolbar'; +import { Checkbox } from 'primereact/checkbox'; +import { Divider } from 'primereact/divider'; +import { Badge } from 'primereact/badge'; import { classNames } from 'primereact/utils'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react'; import { ProductService } from '../../../../demo/service/ProductService'; import { Demo } from '@/types'; @@ -31,21 +39,96 @@ const Crud = () => { inventoryStatus: 'INSTOCK' }; - const [products, setProducts] = useState(null); + const [products, setProducts] = useState([]); const [productDialog, setProductDialog] = useState(false); const [deleteProductDialog, setDeleteProductDialog] = useState(false); const [deleteProductsDialog, setDeleteProductsDialog] = useState(false); const [product, setProduct] = useState(emptyProduct); - const [selectedProducts, setSelectedProducts] = useState(null); + const [selectedProducts, setSelectedProducts] = useState(null); const [submitted, setSubmitted] = useState(false); const [globalFilter, setGlobalFilter] = useState(''); + const [loading, setLoading] = useState(true); + const [filters, setFilters] = useState({}); + const [selectedCategories, setSelectedCategories] = useState([]); + const [selectedStatuses, setSelectedStatuses] = useState([]); + const [priceRange, setPriceRange] = useState(null); + const [ratingFilter, setRatingFilter] = useState(null); + const [quantityFilter, setQuantityFilter] = useState(null); + const [showAdvancedFilters, setShowAdvancedFilters] = useState(false); + const [lastUpdated, setLastUpdated] = useState(null); + const [refreshCount, setRefreshCount] = useState(0); const toast = useRef(null); - const dt = useRef>(null); + const dt = useRef>(null); + + const categories = ['Accessories', 'Clothing', 'Electronics', 'Fitness']; + const inventoryStatuses = ['INSTOCK', 'LOWSTOCK', 'OUTOFSTOCK']; + const priceOptions = [ + { label: 'All Prices', value: null }, + { label: 'Under $50', value: 50 }, + { label: 'Under $100', value: 100 }, + { label: 'Under $200', value: 200 }, + { label: 'Under $500', value: 500 } + ]; + const ratingOptions = [ + { label: 'All Ratings', value: null }, + { label: '5 Stars', value: 5 }, + { label: '4 Stars & Up', value: 4 }, + { label: '3 Stars & Up', value: 3 }, + { label: '2 Stars & Up', value: 2 }, + { label: '1 Star & Up', value: 1 } + ]; + const quantityOptions = [ + { label: 'All Quantities', value: null }, + { label: 'In Stock (Qty > 0)', value: 'instock' }, + { label: 'Low Stock (Qty < 10)', value: 'low' }, + { label: 'Out of Stock (Qty = 0)', value: 'out' } + ]; + + const quickFilters = [ + { label: 'All Products', value: 'all', icon: 'pi pi-box' }, + { label: 'In Stock', value: 'instock', icon: 'pi pi-check-circle' }, + { label: 'Low Stock', value: 'lowstock', icon: 'pi pi-exclamation-triangle' }, + { label: 'Out of Stock', value: 'outofstock', icon: 'pi pi-times-circle' } + ]; + + const [activeQuickFilter, setActiveQuickFilter] = useState('all'); useEffect(() => { - ProductService.getProducts().then((data) => setProducts(data as any)); + initFilters(); + loadProducts(); + }, [refreshCount]); + + const loadProducts = useCallback(() => { + setLoading(true); + ProductService.getProducts().then((data) => { + setProducts(data as Demo.Product[]); + setLoading(false); + setLastUpdated(new Date()); + }); }, []); + const initFilters = () => { + setFilters({ + global: { value: null, matchMode: FilterMatchMode.CONTAINS }, + name: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }] + }, + category: { + operator: FilterOperator.OR, + constraints: [{ value: null, matchMode: FilterMatchMode.IN }] + }, + price: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.LTE }] + }, + inventoryStatus: { + operator: FilterOperator.OR, + constraints: [{ value: null, matchMode: FilterMatchMode.IN }] + } + }); + }; + const formatCurrency = (value: number) => { return value.toLocaleString('en-US', { style: 'currency', @@ -53,6 +136,134 @@ const Crud = () => { }); }; + const stats = useMemo(() => { + const total = products.length; + const inStock = products.filter((p) => p.inventoryStatus === 'INSTOCK').length; + const lowStock = products.filter((p) => p.inventoryStatus === 'LOWSTOCK').length; + const outOfStock = products.filter((p) => p.inventoryStatus === 'OUTOFSTOCK').length; + return { total, inStock, lowStock, outOfStock }; + }, [products]); + + const getFilteredProducts = useCallback(() => { + let filtered = [...products]; + + if (globalFilter) { + const filter = globalFilter.toLowerCase(); + filtered = filtered.filter( + (p) => + (p.name && p.name.toLowerCase().includes(filter)) || + (p.code && p.code.toLowerCase().includes(filter)) || + (p.category && p.category.toLowerCase().includes(filter)) + ); + } + + if (selectedCategories.length > 0) { + filtered = filtered.filter((p) => p.category && selectedCategories.includes(p.category)); + } + + if (selectedStatuses.length > 0) { + filtered = filtered.filter((p) => p.inventoryStatus && selectedStatuses.includes(p.inventoryStatus)); + } + + if (priceRange !== null) { + filtered = filtered.filter((p) => (p.price || 0) <= priceRange); + } + + if (ratingFilter !== null) { + filtered = filtered.filter((p) => (p.rating || 0) >= ratingFilter); + } + + if (quantityFilter) { + switch (quantityFilter) { + case 'instock': + filtered = filtered.filter((p) => (p.quantity || 0) > 0); + break; + case 'low': + filtered = filtered.filter((p) => (p.quantity || 0) > 0 && (p.quantity || 0) < 10); + break; + case 'out': + filtered = filtered.filter((p) => (p.quantity || 0) === 0); + break; + } + } + + if (activeQuickFilter !== 'all') { + switch (activeQuickFilter) { + case 'instock': + filtered = filtered.filter((p) => p.inventoryStatus === 'INSTOCK'); + break; + case 'lowstock': + filtered = filtered.filter((p) => p.inventoryStatus === 'LOWSTOCK'); + break; + case 'outofstock': + filtered = filtered.filter((p) => p.inventoryStatus === 'OUTOFSTOCK'); + break; + } + } + + return filtered; + }, [products, globalFilter, selectedCategories, selectedStatuses, priceRange, ratingFilter, quantityFilter, activeQuickFilter]); + + const filteredCount = useMemo(() => { + if (loading) return 0; + return getFilteredProducts().length; + }, [loading, getFilteredProducts]); + + const getStatusSeverity = (status: string) => { + switch (status) { + case 'INSTOCK': + return 'success'; + case 'LOWSTOCK': + return 'warning'; + case 'OUTOFSTOCK': + return 'danger'; + default: + return 'info'; + } + }; + + const getStatusLabel = (status: string) => { + switch (status) { + case 'INSTOCK': + return 'In Stock'; + case 'LOWSTOCK': + return 'Low Stock'; + case 'OUTOFSTOCK': + return 'Out of Stock'; + default: + return status; + } + }; + + const getCategoryIcon = (category: string) => { + switch (category) { + case 'Accessories': + return 'pi pi-star'; + case 'Clothing': + return 'pi pi-shopping-bag'; + case 'Electronics': + return 'pi pi-mobile'; + case 'Fitness': + return 'pi pi-heart'; + default: + return 'pi pi-box'; + } + }; + + const clearAllFilters = () => { + setSelectedCategories([]); + setSelectedStatuses([]); + setPriceRange(null); + setGlobalFilter(''); + setRatingFilter(null); + setQuantityFilter(null); + setActiveQuickFilter('all'); + initFilters(); + }; + + const hasActiveFilters = selectedCategories.length > 0 || selectedStatuses.length > 0 || priceRange !== null || + ratingFilter !== null || quantityFilter !== null || activeQuickFilter !== 'all'; + const openNew = () => { setProduct(emptyProduct); setSubmitted(false); @@ -152,6 +363,12 @@ const Crud = () => { const exportCSV = () => { dt.current?.exportCSV(); + toast.current?.show({ + severity: 'info', + summary: 'Export Started', + detail: 'Exporting products to CSV...', + life: 2000 + }); }; const confirmDeleteSelected = () => { @@ -207,6 +424,14 @@ const Crud = () => { const rightToolbarTemplate = () => { return ( +