fixed issues with app
This commit is contained in:
+21
-8
@@ -1,5 +1,13 @@
|
||||
import { query } from './_generated/server.js';
|
||||
import { requireOwner } from './lib.js';
|
||||
import { dashboardRangeValidator } from './validators.js';
|
||||
|
||||
const rangeDays = {
|
||||
'7d': 7,
|
||||
'30d': 30,
|
||||
'90d': 90,
|
||||
'1y': 365
|
||||
} as const;
|
||||
|
||||
function dayKey(date: Date) {
|
||||
return date.toISOString().slice(0, 10);
|
||||
@@ -13,24 +21,27 @@ function daysAgo(days: number) {
|
||||
}
|
||||
|
||||
export const summary = query({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
args: { range: dashboardRangeValidator },
|
||||
handler: async (ctx, args) => {
|
||||
const owner = await requireOwner(ctx);
|
||||
const selectedDays = rangeDays[args.range];
|
||||
const entries = await ctx.db
|
||||
.query('entries')
|
||||
.withIndex('by_owner_and_entryDate', (q) => q.eq('owner', owner))
|
||||
.order('desc')
|
||||
.take(250);
|
||||
.take(Math.min(800, selectedDays * 3));
|
||||
const activeEntries = entries.filter((entry) => !entry.archived);
|
||||
const last30Start = daysAgo(29);
|
||||
const rangeStart = daysAgo(selectedDays - 1);
|
||||
const last7Start = daysAgo(6);
|
||||
const last30 = activeEntries.filter((entry) => entry.entryDate >= last30Start);
|
||||
const last30Start = daysAgo(29);
|
||||
const rangedEntries = activeEntries.filter((entry) => entry.entryDate >= rangeStart);
|
||||
const last7 = activeEntries.filter((entry) => entry.entryDate >= last7Start);
|
||||
const last30 = activeEntries.filter((entry) => entry.entryDate >= last30Start);
|
||||
const moodCounts: Record<string, number> = {};
|
||||
const dailyCounts = new Map<string, number>();
|
||||
const tagCounts: Record<string, number> = {};
|
||||
|
||||
for (const entry of last30) {
|
||||
for (const entry of rangedEntries) {
|
||||
moodCounts[entry.mood] = (moodCounts[entry.mood] ?? 0) + 1;
|
||||
dailyCounts.set(entry.entryDate, (dailyCounts.get(entry.entryDate) ?? 0) + 1);
|
||||
|
||||
@@ -46,8 +57,8 @@ export const summary = query({
|
||||
currentStreak += 1;
|
||||
}
|
||||
|
||||
const dailySeries = Array.from({ length: 30 }, (_, index) => {
|
||||
const date = daysAgo(29 - index);
|
||||
const dailySeries = Array.from({ length: selectedDays }, (_, index) => {
|
||||
const date = daysAgo(selectedDays - 1 - index);
|
||||
return { date, count: dailyCounts.get(date) ?? 0 };
|
||||
});
|
||||
|
||||
@@ -55,6 +66,8 @@ export const summary = query({
|
||||
totalEntries: activeEntries.length,
|
||||
entriesThisWeek: last7.length,
|
||||
entriesThisMonth: last30.length,
|
||||
entriesInRange: rangedEntries.length,
|
||||
range: args.range,
|
||||
currentStreak,
|
||||
averageWords:
|
||||
activeEntries.length === 0
|
||||
|
||||
@@ -19,6 +19,46 @@ const sortValidator = v.union(
|
||||
v.literal('title')
|
||||
);
|
||||
|
||||
const markdownGuideBody = `# Markdown basics
|
||||
|
||||
Welcome to Journaley. This starter entry shows the markdown features you can use while journaling.
|
||||
|
||||
## Formatting
|
||||
|
||||
Use **bold** for emphasis, _italic_ for gentle notes, and \`inline code\` for short snippets.
|
||||
|
||||
## Lists
|
||||
|
||||
- Capture loose thoughts
|
||||
- Group ideas by theme
|
||||
- Keep reflections scannable
|
||||
|
||||
1. Start with what happened
|
||||
2. Add how it felt
|
||||
3. Close with one next step
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Try writing one short entry
|
||||
- [ ] Add a few tags
|
||||
- [ ] Search for this guide later
|
||||
|
||||
## Quotes
|
||||
|
||||
> A small daily note is still a thread you can return to.
|
||||
|
||||
## Links and tables
|
||||
|
||||
[Markdown guide](https://www.markdownguide.org/basic-syntax/)
|
||||
|
||||
| Syntax | Result |
|
||||
| --- | --- |
|
||||
| **bold** | bold text |
|
||||
| _italic_ | italic text |
|
||||
| # Heading | section title |
|
||||
|
||||
You can edit or delete this entry whenever you want.`;
|
||||
|
||||
type EntryWithTags = Doc<'entries'> & {
|
||||
tags: Doc<'tags'>[];
|
||||
};
|
||||
@@ -258,6 +298,65 @@ export const create = mutation({
|
||||
}
|
||||
});
|
||||
|
||||
export const ensureMarkdownGuideEntry = mutation({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
const owner = await requireOwner(ctx);
|
||||
const existingState = await ctx.db
|
||||
.query('userState')
|
||||
.withIndex('by_owner', (q) => q.eq('owner', owner))
|
||||
.unique();
|
||||
|
||||
if (existingState?.markdownGuideSeeded) {
|
||||
return existingState.markdownGuideEntryId ?? null;
|
||||
}
|
||||
|
||||
const tags = await ensureTags(ctx, owner, ['markdown', 'guide']);
|
||||
const now = Date.now();
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const plainText = markdownToPlainText(markdownGuideBody);
|
||||
const entryId = await ctx.db.insert('entries', {
|
||||
owner,
|
||||
title: 'Markdown basics',
|
||||
body: markdownGuideBody,
|
||||
plainText,
|
||||
searchText: buildSearchText({
|
||||
title: 'Markdown basics',
|
||||
body: markdownGuideBody,
|
||||
mood: 'neutral',
|
||||
tagNames: tags.map((tag) => tag.name)
|
||||
}),
|
||||
mood: 'neutral',
|
||||
entryDate: today,
|
||||
tagNames: tags.map((tag) => tag.name),
|
||||
tagSlugs: tags.map((tag) => tag.slug),
|
||||
pinned: true,
|
||||
archived: false,
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
});
|
||||
|
||||
await applyEntryTags(ctx, owner, entryId, tags);
|
||||
|
||||
if (existingState) {
|
||||
await ctx.db.patch(existingState._id, {
|
||||
markdownGuideSeeded: true,
|
||||
markdownGuideEntryId: entryId,
|
||||
updatedAt: now
|
||||
});
|
||||
} else {
|
||||
await ctx.db.insert('userState', {
|
||||
owner,
|
||||
markdownGuideSeeded: true,
|
||||
markdownGuideEntryId: entryId,
|
||||
updatedAt: now
|
||||
});
|
||||
}
|
||||
|
||||
return entryId;
|
||||
}
|
||||
});
|
||||
|
||||
export const update = mutation({
|
||||
args: {
|
||||
entryId: v.id('entries'),
|
||||
|
||||
@@ -61,5 +61,11 @@ export default defineSchema({
|
||||
editorMode: editorModeValidator,
|
||||
dashboardRange: dashboardRangeValidator,
|
||||
updatedAt: v.number()
|
||||
}).index('by_owner', ['owner']),
|
||||
userState: defineTable({
|
||||
owner: v.string(),
|
||||
markdownGuideSeeded: v.boolean(),
|
||||
markdownGuideEntryId: v.optional(v.id('entries')),
|
||||
updatedAt: v.number()
|
||||
}).index('by_owner', ['owner'])
|
||||
});
|
||||
|
||||
@@ -23,4 +23,9 @@ export const editorModeValidator = v.union(
|
||||
v.literal('preview')
|
||||
);
|
||||
|
||||
export const dashboardRangeValidator = v.union(v.literal('7d'), v.literal('30d'), v.literal('90d'));
|
||||
export const dashboardRangeValidator = v.union(
|
||||
v.literal('7d'),
|
||||
v.literal('30d'),
|
||||
v.literal('90d'),
|
||||
v.literal('1y')
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user