project init

This commit is contained in:
marcelolop 2024-06-25 10:15:38 -05:00
parent d5415b7747
commit 2fc27fa500

View File

@ -1,13 +1,12 @@
import { $, component$, useStore, useSignal } from "@builder.io/qwik"; import { $, component$, useStore, useSignal } from "@builder.io/qwik";
import { useCSSTransition } from "qwik-transition"; import { useCSSTransition } from "qwik-transition";
import Icon from "~/components/core/icon"; import Icon from "~/components/core/icon"; // Verifique se o caminho está correto
import type { Priority, Section, Checklist } from '../../types/PSC'; import type { Priority, Section, Checklist } from '../../types/PSC';
import { marked } from "marked"; import { marked } from "marked";
import { useLocalStorage } from "~/hooks/useLocalStorage"; import { useLocalStorage } from "~/hooks/useLocalStorage";
import styles from './psc.module.css'; import styles from './psc.module.css';
export default component$((props: { section: Section }) => { export default component$((props: { section: Section }) => {
const [completed, setCompleted] = useLocalStorage('PSC_PROGRESS', {}); const [completed, setCompleted] = useLocalStorage('PSC_PROGRESS', {});
@ -56,7 +55,6 @@ export default component$((props: { section: Section }) => {
return ignored.value[pointId] || false; return ignored.value[pointId] || false;
}; };
const isChecked = (pointId: string) => { const isChecked = (pointId: string) => {
if (isIgnored(pointId)) return false; if (isIgnored(pointId)) return false;
return completed.value[pointId] || false; return completed.value[pointId] || false;
@ -104,14 +102,14 @@ export default component$((props: { section: Section }) => {
} }
}; };
const handleSort = $((column: string) => { // const handleSort = $((column: string) => {
if (sortState.column === column) { // Reverse direction if same column // if (sortState.column === column) { // Reverse direction if same column
sortState.ascending = !sortState.ascending; // sortState.ascending = !sortState.ascending;
} else { // Sort table by column // } else { // Sort table by column
sortState.column = column; // sortState.column = column;
sortState.ascending = true; // Default to ascending // sortState.ascending = true; // Default to ascending
} // }
}); // });
const resetFilters = $(() => { const resetFilters = $(() => {
checklist.value = props.section.checklist; checklist.value = props.section.checklist;
@ -121,7 +119,7 @@ export default component$((props: { section: Section }) => {
filterState.show = originalFilters.show; filterState.show = originalFilters.show;
}); });
const calculateProgress = (): { done: number, total: number, percent: number, disabled: number} => { const calculateProgress = (): { done: number, total: number, percent: number, disabled: number } => {
let done = 0; let done = 0;
let disabled = 0; let disabled = 0;
let total = 0; let total = 0;
@ -146,7 +144,6 @@ export default component$((props: { section: Section }) => {
return ( return (
<> <>
<div class="flex flex-wrap justify-between items-center"> <div class="flex flex-wrap justify-between items-center">
<div> <div>
<progress class="progress w-64" value={percent} max="100"></progress> <progress class="progress w-64" value={percent} max="100"></progress>
@ -158,12 +155,12 @@ export default component$((props: { section: Section }) => {
<div class="flex flex-wrap gap-2 justify-end my-4"> <div class="flex flex-wrap gap-2 justify-end my-4">
{(sortState.column || JSON.stringify(filterState) !== JSON.stringify(originalFilters)) && ( {(sortState.column || JSON.stringify(filterState) !== JSON.stringify(originalFilters)) && (
<button class="btn btn-sm hover:btn-primary" onClick$={resetFilters}> <button class="btn btn-sm hover:btn-primary" onClick$={resetFilters}>
<Icon width={18} height={16} icon="clear"/> <Icon width={18} height={16} icon="clear" />
Reset Filters Reset Filters
</button> </button>
)} )}
<button class="btn btn-sm hover:btn-primary" onClick$={() => { showFilters.value = !showFilters.value; }}> <button class="btn btn-sm hover:btn-primary" onClick$={() => { showFilters.value = !showFilters.value; }}>
<Icon width={18} height={16} icon="filters"/> <Icon width={18} height={16} icon="filters" />
{showFilters.value ? 'Hide' : 'Show'} Filters {showFilters.value ? 'Hide' : 'Show'} Filters
</button> </button>
</div> </div>
@ -178,24 +175,24 @@ export default component$((props: { section: Section }) => {
<label onClick$={() => (filterState.show = 'all')} <label onClick$={() => (filterState.show = 'all')}
class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2"> class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2">
<span class="text-sm">All</span> <span class="text-sm">All</span>
<input type="radio" name="show" class="radio radio-sm checked:radio-info" checked /> <input type="radio" name="show" class="radio radio-sm checked:radio-info" checked={filterState.show === 'all'} />
</label> </label>
<label onClick$={() => (filterState.show = 'remaining')} <label onClick$={() => (filterState.show = 'remaining')}
class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2"> class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2">
<span class="text-sm">Remaining</span> <span class="text-sm">Remaining</span>
<input type="radio" name="show" class="radio radio-sm checked:radio-error" /> <input type="radio" name="show" class="radio radio-sm checked:radio-error" checked={filterState.show === 'remaining'} />
</label> </label>
<label onClick$={() => (filterState.show = 'completed')} <label onClick$={() => (filterState.show = 'completed')}
class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2"> class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2">
<span class="text-sm">Completed</span> <span class="text-sm">Completed</span>
<input type="radio" name="show" class="radio radio-sm checked:radio-success" /> <input type="radio" name="show" class="radio radio-sm checked:radio-success" checked={filterState.show === 'completed'} />
</label> </label>
</div> </div>
{/* Filter by level */} {/* Filter by level */}
<div class="flex justify-end items-center gap-1"> <div class="flex justify-end items-center gap-1">
<p class="font-bold text-sm">Filter</p> <p class="font-bold text-sm">Filter</p>
<label class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2"> <label class="p-2 rounded hover:bg-front transition-all cursor-pointer flex gap-2">
<span class="text-sm">Basic</span> <span class="text-sm">Essential</span>
<input <input
type="checkbox" type="checkbox"
checked={filterState.levels.essential} checked={filterState.levels.essential}
@ -226,45 +223,42 @@ export default component$((props: { section: Section }) => {
</div> </div>
)} )}
<table class="table"> <div class="grid grid-cols-1 gap-4">
<thead>
<tr>
{ [
{ id: 'done', text: 'Done?'},
{ id: 'advice', text: 'Advice' },
{ id: 'level', text: 'Level' }
].map((item) => (
<th
key={item.id}
class="cursor-pointer"
onClick$={() => handleSort(item.id)}
>
<span class="flex items-center gap-0.5 hover:text-primary transition">
<Icon width={12} height={14} icon="sort" />
{item.text}
</span>
</th>
))}
<th>Details</th>
</tr>
</thead>
<tbody>
{filteredChecklist.sort(sortChecklist).map((item, index) => { {filteredChecklist.sort(sortChecklist).map((item, index) => {
const badgeColor = getBadgeClass(item.priority); const badgeColor = getBadgeClass(item.priority);
const itemId = generateId(item.point); const itemId = generateId(item.point);
const isItemCompleted = isChecked(itemId); const isItemCompleted = isChecked(itemId);
const isItemIgnored = isIgnored(itemId); const isItemIgnored = isIgnored(itemId);
return ( return (
<tr key={index} class={[ <details
'rounded-sm transition-all', key={index}
isItemCompleted ? `bg-${badgeColor} bg-opacity-10` : '', class={[
isItemIgnored? 'bg-neutral bg-opacity-15' : '', 'rounded-lg p-4 shadow transition-all',
isItemCompleted ? `bg-${badgeColor} bg-opacity-10` : 'bg-base-100',
isItemIgnored ? 'opacity-50' : '',
!isItemIgnored && !isItemCompleted ? `hover:bg-opacity-5 hover:bg-${badgeColor}` : '', !isItemIgnored && !isItemCompleted ? `hover:bg-opacity-5 hover:bg-${badgeColor}` : '',
]}> ].join(' ')}
<td class="text-center"> >
<summary class="flex justify-between items-center cursor-pointer">
<div class="flex-1 flex items-center gap-2">
<div class="flex flex-col gap-2">
<div class={`badge font-[600] gap-2 badge-${badgeColor}`}>
{item.priority}
</div>
<label for={`done-${itemId}`} class={`text-base font-bold ${isIgnored(itemId) ? 'line-through' : ''}`}>
{item.point}
</label>
</div>
<Icon width={18} height={16} icon="chevron-down" class={`${styles.arrow} ${styles.summaryIcon}`} />
</div>
<div class="flex gap-2 items-center">
<div class="flex items-center gap-1">
<label for={`done-${itemId}`} class="text-xs">Done</label>
<input <input
type="checkbox" type="radio"
class={`checkbox checked:checkbox-${badgeColor} hover:checkbox-${badgeColor}`} name={`status-${itemId}`}
class={`radio radio-${badgeColor}`}
id={`done-${itemId}`} id={`done-${itemId}`}
checked={isChecked(itemId)} checked={isChecked(itemId)}
disabled={isIgnored(itemId)} disabled={isIgnored(itemId)}
@ -274,11 +268,14 @@ export default component$((props: { section: Section }) => {
setCompleted(data); setCompleted(data);
}} }}
/> />
<label for={`ignore-${itemId}`} class="text-small block opacity-50 mt-2">Ignore</label> </div>
<div class="flex items-center gap-1">
<label for={`ignore-${itemId}`} class="text-xs">Ignore</label>
<input <input
type="checkbox" type="radio"
name={`status-${itemId}`}
class={`radio radio-${badgeColor}`}
id={`ignore-${itemId}`} id={`ignore-${itemId}`}
class={`toggle toggle-xs toggle-${badgeColor}`}
checked={isIgnored(itemId)} checked={isIgnored(itemId)}
onClick$={() => { onClick$={() => {
const ignoredData = ignored.value; const ignoredData = ignored.value;
@ -290,25 +287,14 @@ export default component$((props: { section: Section }) => {
setCompleted(completedData); setCompleted(completedData);
}} }}
/> />
</td>
<td>
<label
for={`done-${itemId}`}
class={`text-base font-bold ${isIgnored(itemId) ? 'line-through' : 'cursor-pointer'}`}>
{item.point}
</label>
</td>
<td>
<div class={`badge gap-2 badge-${badgeColor}`}>
{item.priority}
</div> </div>
</td> </div>
<td class={styles.checklistItemDescription} dangerouslySetInnerHTML={parseMarkdown(item.details)}></td> </summary>
</tr> <div class={styles.checklistItemDescription} dangerouslySetInnerHTML={parseMarkdown(item.details)}></div>
)} </details>
)} )
</tbody> })}
</table> </div>
</> </>
); );
}); });