Skip to content

Commit

Permalink
feat: Disable changing key for title and author fields in Upload page
Browse files Browse the repository at this point in the history
This commit adds the `disabled` attribute to the input field for the `key` property in the Upload page. The `disabled` attribute is set to `true` when the `key` is either 'title' or 'author', preventing users from changing these fields. This change ensures that the title and author fields remain consistent and cannot be modified accidentally.
  • Loading branch information
bramses committed Aug 28, 2024
1 parent e2c91e9 commit c029f79
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 107 deletions.
247 changes: 141 additions & 106 deletions src/app/[locale]/(auth)/dashboard/garden/page.tsx
Original file line number Diff line number Diff line change
@@ -1,136 +1,171 @@
'use client';

import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useCallback, useEffect, useState } from 'react';
import Calendar from 'react-calendar';

import Entry from '@/components/Entry';
import { getCache, invalidateCache, setCache } from '@/helpers/cache';

const GardenDaily = () => {
const router = useRouter();
const searchParams = useSearchParams();
const [entries, setEntries] = useState<any[]>([]);
const [selectedDay, setSelectedDay] = useState('');
const [loading, setLoading] = useState(false);
const cache = getCache();

const fetchByID = async (id: string) => {
const cachedAlias = cache.aliases[id];
if (cachedAlias) {
// console.log('Returning cached alias:', cachedAlias);
return { data: cachedAlias };
}
const fetchByID = useCallback(
async (id: string) => {
const cachedAlias = cache.aliases[id];
if (cachedAlias) {
// console.log('Returning cached alias:', cachedAlias);
return { data: cachedAlias };
}

// TODO: this breaks w aliases updating and idk how to fix atm
// const cachedParent = cache.parents[id];
// if (cachedParent) {
// // console.log('Returning cached parent:', cachedParent);
// return { data: cachedParent };
// }
// TODO: this breaks w aliases updating and idk how to fix atm
// const cachedParent = cache.parents[id];
// if (cachedParent) {
// // console.log('Returning cached parent:', cachedParent);
// return { data: cachedParent };
// }

try {
const response = await fetch('/api/fetch', {
try {
const response = await fetch('/api/fetch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id,
}),
});
const data = await response.json();
const entry = data.data;
// parse metadata
const metadata = JSON.parse(entry.metadata);

// cache the entry
if (metadata.parent_id) {
cache.aliases[id] = entry;
} else {
cache.parents[id] = entry;
}

setCache(cache);

return data;
} catch (error) {
console.error('Error fetching entry by ID:', error);
return {};
}
},
[cache],
);

const fetchRecords = useCallback(
async (date: Date) => {
// convert date to form 2024-01-01
const year = date.getFullYear();
const month = date.getMonth() + 1;
let monthString = month.toString();
// put a 0 in front of month if it is less than 10
if (month < 10) {
monthString = `0${month}`;
}
const day = date.getDate();
let dayString = day.toString();
if (day < 10) {
dayString = `0${day}`;
}
const dateString = `${year}-${monthString}-${dayString}`;
setSelectedDay(dateString);
setLoading(true);
// run a post request to fetch records for that date at /api/daily
const response = await fetch('/api/daily', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id,
}),
body: JSON.stringify({ date: dateString }),
});
const responseData = await response.json();
console.log('Fetched records:', responseData);
// map over the response data and turn metadata into an object
// set entries to the mapped data
const mappedData = responseData.data.map((entry: any) => {
return {
...entry,
metadata: JSON.parse(entry.metadata),
};
});
const data = await response.json();
const entry = data.data;
// parse metadata
const metadata = JSON.parse(entry.metadata);

// cache the entry
if (metadata.parent_id) {
cache.aliases[id] = entry;
} else {
cache.parents[id] = entry;
}
// get existing aliases for each entry
const aliasData = await Promise.all(
mappedData.map(async (entry: any) => {
if (entry.metadata.alias_ids) {
try {
const aliasDataMap = await Promise.all(
entry.metadata.alias_ids.map(async (aliasId: string) => {
try {
const aliasEntryRes = await fetchByID(aliasId);
const aliasEntry = aliasEntryRes.data;
return aliasEntry.data;
} catch (aliasFetchError) {
console.error(
`Error fetching alias entry with ID ${aliasId}:`,
aliasFetchError,
);
throw aliasFetchError;
}
}),
);

setCache(cache);
return {
...entry,
aliasData: aliasDataMap,
};
} catch (aliasError) {
console.error('Error fetching aliases:', aliasError);
return { ...entry };
}
}
return entry;
}),
);

return data;
} catch (error) {
console.error('Error fetching entry by ID:', error);
return {};
}
};
setLoading(false);
setEntries(aliasData);
},
[fetchByID, setSelectedDay, setLoading, setEntries],
);

const fetchRecords = async (date: Date) => {
// convert date to form 2024-01-01
const year = date.getFullYear();
const month = date.getMonth() + 1;
let monthString = month.toString();
// put a 0 in front of month if it is less than 10
if (month < 10) {
monthString = `0${month}`;
}
const day = date.getDate();
let dayString = day.toString();
if (day < 10) {
dayString = `0${day}`;
// on load page, fetch all entries for the current day
useEffect(() => {
const today = new Date();
let dateParam = today;
if (searchParams && searchParams.has('date')) {
let searchParamsDate = searchParams.get('date') as string;
// if date comes in form 07-31-2024 convert it to 2024-07-31
const dateParts = (searchParams.get('date') as string).split('-');
if (dateParts.length === 3) {
searchParamsDate = `${dateParts[2]}-${dateParts[0]}-${dateParts[1]}`;
}
// convert 2024-08-26 to Date Sun Aug 26 2024 in UTC
// const dateString = searchParams.get('date') as string;
// add a day to the date to get the correct date this is so stupid
const datePlusOne = new Date(`${searchParamsDate}T00:00:00Z`);
dateParam = new Date(datePlusOne.setDate(datePlusOne.getDate() + 1));
}
const dateString = `${year}-${monthString}-${dayString}`;
setSelectedDay(dateString);
setLoading(true);
// run a post request to fetch records for that date at /api/daily
const response = await fetch('/api/daily', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ date: dateString }),
});
const responseData = await response.json();
// map over the response data and turn metadata into an object
// set entries to the mapped data
const mappedData = responseData.data.map((entry: any) => {
return {
...entry,
metadata: JSON.parse(entry.metadata),
};
});

// get existing aliases for each entry
const aliasData = await Promise.all(
mappedData.map(async (entry: any) => {
if (entry.metadata.alias_ids) {
try {
const aliasDataMap = await Promise.all(
entry.metadata.alias_ids.map(async (aliasId: string) => {
try {
const aliasEntryRes = await fetchByID(aliasId);
const aliasEntry = aliasEntryRes.data;
return aliasEntry.data;
} catch (aliasFetchError) {
console.error(
`Error fetching alias entry with ID ${aliasId}:`,
aliasFetchError,
);
throw aliasFetchError;
}
}),
);
const formattedDateParam = `${dateParam.getUTCFullYear()}-${(
dateParam.getUTCMonth() + 1
)
.toString()
.padStart(2, '0')}-${dateParam.getUTCDate().toString().padStart(2, '0')}`;

return {
...entry,
aliasData: aliasDataMap,
};
} catch (aliasError) {
console.error('Error fetching aliases:', aliasError);
return { ...entry };
}
}
return entry;
}),
);

setLoading(false);
setEntries(aliasData);
};
setSelectedDay(formattedDateParam);
fetchRecords(dateParam);
}, [searchParams]);

const addEntry = async (data: string, metadata: string) => {
try {
Expand Down
2 changes: 2 additions & 0 deletions src/app/[locale]/(auth)/dashboard/upload/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ const Upload = () => {
className="block w-1/2 rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder:text-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
placeholder="Key"
value={field.key}
// if key is title or author, don't allow to change
disabled={field.key === 'title' || field.key === 'author'}
onChange={(e) => handleFieldChange(index, 'key', e.target.value)}
/>
<input
Expand Down
13 changes: 12 additions & 1 deletion src/components/Entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,18 @@ const Entry = ({
<p className="mb-3 font-normal text-gray-500 dark:text-gray-400">
Added on{' '}
<strong className="font-semibold text-gray-900 dark:text-white">
{new Date(createdAt).toLocaleDateString()}
{/* link to /dashboard/garden?date=yyyy-mm-dd. if day or month is one number prepend a zero */}
<a
href={`/dashboard/garden?date=${new Date(createdAt)
.toLocaleDateString()
.split('/')
.map((d) => (d.length === 1 ? `0${d}` : d))
.join('-')}
`}
className="text-blue-600 hover:underline"
>
{new Date(createdAt).toLocaleDateString()}
</a>
</strong>{' '}
with a similarity of{' '}
<strong className="font-semibold text-gray-900 dark:text-white">
Expand Down

0 comments on commit c029f79

Please sign in to comment.