mirror of
https://github.com/soconnor0919/hristudio.git
synced 2025-12-11 14:44:44 -05:00
Enhance development standards and UI components
- Updated .rules to enforce stricter UI/UX standards, including exclusive use of Lucide icons and consistent patterns for entity view pages. - Added new UI components for entity views, including headers, sections, and quick actions to improve layout and reusability. - Refactored existing pages (experiments, participants, studies, trials) to utilize the new entity view components, enhancing consistency across the dashboard. - Improved accessibility and user experience by implementing loading states and error boundaries in async operations. - Updated package dependencies to ensure compatibility and performance improvements. Features: - Comprehensive guidelines for component reusability and visual consistency. - Enhanced user interface with new entity view components for better organization and navigation. Breaking Changes: None - existing functionality remains intact.
This commit is contained in:
@@ -128,23 +128,24 @@ export const trialsRouter = createTRPCRouter({
|
||||
id: participants.id,
|
||||
participantCode: participants.participantCode,
|
||||
},
|
||||
userRole: studyMembers.role,
|
||||
})
|
||||
.from(trials)
|
||||
.innerJoin(experiments, eq(trials.experimentId, experiments.id))
|
||||
.innerJoin(participants, eq(trials.participantId, participants.id))
|
||||
.innerJoin(studyMembers, eq(studyMembers.studyId, experiments.studyId))
|
||||
.where(
|
||||
and(
|
||||
eq(studyMembers.userId, userId),
|
||||
inArray(studyMembers.role, ["owner", "researcher", "wizard"]),
|
||||
...conditions,
|
||||
),
|
||||
)
|
||||
.where(and(eq(studyMembers.userId, userId), ...conditions))
|
||||
.orderBy(desc(trials.createdAt))
|
||||
.limit(input.limit)
|
||||
.offset(input.offset);
|
||||
|
||||
return await query;
|
||||
const results = await query;
|
||||
|
||||
// Add permission flags for each trial
|
||||
return results.map((trial) => ({
|
||||
...trial,
|
||||
canAccess: ["owner", "researcher", "wizard"].includes(trial.userRole),
|
||||
}));
|
||||
}),
|
||||
|
||||
get: protectedProcedure
|
||||
@@ -575,15 +576,19 @@ export const trialsRouter = createTRPCRouter({
|
||||
const offset = (page - 1) * limit;
|
||||
const userId = ctx.session.user.id;
|
||||
|
||||
// Get all studies user is a member of
|
||||
// Get all studies user is a member of with roles
|
||||
const userStudies = await ctx.db.query.studyMembers.findMany({
|
||||
where: eq(studyMembers.userId, userId),
|
||||
columns: {
|
||||
studyId: true,
|
||||
role: true,
|
||||
},
|
||||
});
|
||||
|
||||
let studyIds = userStudies.map((membership) => membership.studyId);
|
||||
const userStudyRoles = new Map(
|
||||
userStudies.map((membership) => [membership.studyId, membership.role]),
|
||||
);
|
||||
|
||||
// If studyId is provided, filter to just that study (if user has access)
|
||||
if (studyId) {
|
||||
@@ -704,14 +709,22 @@ export const trialsRouter = createTRPCRouter({
|
||||
|
||||
const totalCount = totalCountResult[0]?.count ?? 0;
|
||||
|
||||
// Transform data to include counts
|
||||
const transformedTrials = filteredTrials.map((trial) => ({
|
||||
...trial,
|
||||
_count: {
|
||||
events: trial.events?.length ?? 0,
|
||||
mediaCaptures: trial.mediaCaptures?.length ?? 0,
|
||||
},
|
||||
}));
|
||||
// Transform data to include counts and permission information
|
||||
const transformedTrials = filteredTrials.map((trial) => {
|
||||
const userRole = userStudyRoles.get(trial.experiment.studyId);
|
||||
const canAccess =
|
||||
userRole && ["owner", "researcher", "wizard"].includes(userRole);
|
||||
|
||||
return {
|
||||
...trial,
|
||||
_count: {
|
||||
events: trial.events?.length ?? 0,
|
||||
mediaCaptures: trial.mediaCaptures?.length ?? 0,
|
||||
},
|
||||
userRole,
|
||||
canAccess,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
trials: transformedTrials,
|
||||
|
||||
Reference in New Issue
Block a user