Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Governance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ documents are added and refined over time (tracked as issues):
- **Decision-making** — consensus and voting rules, the RFC/proposal process, and
decision records.
- **Community & conduct** — code of conduct, enforcement, moderation, and conflict
resolution.
resolution, including [communication norms](policies/COMMUNICATION_NORMS.md).
- **Contribution governance** — review policy, triage, labels, and roadmap governance.
- **Security & disclosure** — vulnerability reporting, embargo, and advisory processes.
- **Releases & change** — versioning, release cadence, deprecation, and change policy.
Expand Down
70 changes: 70 additions & 0 deletions Governance/policies/COMMUNICATION_NORMS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Community Communication Norms

**Version:** 1.0

## Purpose and Scope

These norms set expectations for communication among TeachLink Web contributors,
maintainers, and community members. They apply to project-related communication
in the official channels below. They complement the project's conduct and
security policies; they do not replace them.

## Official Channels

- **GitHub Issues** are for actionable bug reports, feature requests, and
project questions that need tracking.
- **GitHub Discussions**, when enabled for this repository, are for open-ended
questions, ideas, and community conversation. If Discussions are unavailable,
use an appropriate issue.
- **Pull requests** are for proposing code or documentation changes and keeping
review feedback and decisions with the proposed change.
- **Security reports** must use the repository's private vulnerability
reporting channel when available. Otherwise, contact a maintainer privately.
Do not publish suspected vulnerabilities, exploit details, credentials, or
personal data in an issue, discussion, or pull request.

Project decisions and actionable outcomes should be recorded in the relevant
repository issue, discussion, or pull request so they remain accessible and
searchable. Do not share private contact details or sensitive information in
public channels.

## Tone and Etiquette

- Be respectful, inclusive, and professional. Critique proposals and work, not
the people behind them.
- Be clear and constructive: provide relevant context, describe the impact, and
suggest a next step when practical.
- Assume good faith, while listening carefully when someone explains that a
message or action caused harm. Correct misunderstandings without personal
attacks or escalation.
- Keep discussion focused and accessible. Avoid repeated messages, personal
call-outs, and cross-posting the same request to pressure a faster response.
- Harassment, discrimination, threats, insults, and deliberate disruption are
not acceptable. Moderation and conduct concerns should be raised privately
with a maintainer rather than argued out in a public thread.

## Response Expectations

TeachLink Web is maintained across time zones and availability varies. The
following are targets, not guarantees or on-call commitments:

- A maintainer should aim to acknowledge a new issue or discussion within three
business days.
- A pull request should aim to receive an initial review or status update within
five business days.
- If a response is delayed, contributors should add one concise follow-up to the
original thread after five business days. Avoid repeated pings; maintainers
will update the thread when they can.
- Security reports should be acknowledged promptly through the private channel,
but are handled under the security response process rather than these public
response targets.

Business-day targets do not require anyone to respond outside their normal
availability. If a request is time-sensitive, explain the reason and impact in
the original thread without implying guaranteed priority.

## Ownership and Changes

Maintainers own this policy. Changes are proposed through a pull request that
touches only the `Governance/` folder, in accordance with the governance
contribution rules.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"recharts": "^2.15.4",
"socket.io": "^4.8.3",
"socket.io-client": "^4.8.3",
"sonner": "^2.0.8",
"tailwind-merge": "^2.6.0",
"uuid": "^14.0.1",
"video.js": "^8.23.7",
Expand Down
20 changes: 20 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/layout/HeaderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useEffect, useState, useMemo, startTransition } from 'react';
import Link from 'next/link';
import { toast } from 'sonner';
import { toast } from 'react-hot-toast';
import { useWallet } from '@/hooks/useWallet';
import { IGrantContext } from '@/types/grants';
import { createLogger } from '@/lib/logging';
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/__tests__/HeaderComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('HeaderComponent — Grant Management Pipeline Verification', () => {
const dropdownButton = await screen.findByText('1 Scope Grant Authorized');
fireEvent.click(dropdownButton);

expect(screen.getByText('BUDGET MANAGEMENT')).toBeInTheDocument();
expect(screen.getByText('budget management')).toBeInTheDocument();

// Mock successful revocation endpoint cycle
(global.fetch as any).mockResolvedValueOnce({ ok: true });
Expand All @@ -66,7 +66,7 @@ describe('HeaderComponent — Grant Management Pipeline Verification', () => {
fireEvent.click(revokeButton);

await waitFor(() => {
expect(screen.queryByText('BUDGET MANAGEMENT')).not.toBeInTheDocument();
expect(screen.queryByText('budget management')).not.toBeInTheDocument();
});
});
});
11 changes: 11 additions & 0 deletions src/hooks/useWallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useWallet as useWalletContext } from '@/providers/WalletProvider';

export function useWallet() {
const wallet = useWalletContext();

return {
...wallet,
connected: wallet.isConnected,
publicKey: wallet.address,
};
}
4 changes: 2 additions & 2 deletions src/providers/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ export function WalletProvider({ children }: WalletProviderProps) {
network: validateWalletEnv().network,
}));

const connect = useCallback(async () => {
const connect = useCallback(async (): Promise<void> => {
setState((prev) => ({ ...prev, isConnecting: true, error: null }));

return walletConnectionQueue.enqueue(async () => {
await walletConnectionQueue.enqueue(async () => {
try {
if (typeof window === 'undefined') {
throw new Error('Window not available');
Expand Down
Loading